package benchmark; import static java.util.Collections.shuffle; import static java.util.stream.Collectors.toList; import static java.util.stream.IntStream.range; import java.util.List; import java.util.Map; import java.util.Random; import java.util.SortedMap; import java.util.TreeMap; import java.util.concurrent.TimeUnit; import org.javersion.core.Diff; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.runner.Runner; import org.openjdk.jmh.runner.RunnerException; import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; import com.google.common.collect.Maps; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) @Fork(1) @State(Scope.Benchmark) public class DiffBenchmark { @Param({"10", "50", "100", "500", "1000", "5000"}) public int size; private List<Integer> intsA; private List<Integer> intsB; private Map<Integer, Integer> hashMapA; private Map<Integer, Integer> hashMapB; private SortedMap<Integer, Integer> sortedMapA; private SortedMap<Integer, Integer> sortedMapB; @Setup public void setup() { intsA = range(0, size).boxed().collect(toList()); shuffle(intsA, new Random(42)); int mid = size / 2; intsB = range(mid, size+mid).boxed().collect(toList()); shuffle(intsB, new Random(42)); hashMapA = map(intsA); hashMapB = map(intsB); sortedMapA = sorted(intsA); sortedMapB = sorted(intsB); } @Benchmark public Map<Integer, Integer> mapDiff() { return Diff.diff(map(intsA), map(intsB)); } @Benchmark public Map<Integer, Integer> sortedDiff() { return Diff.diff(sorted(intsA), sorted(intsB)); } @Benchmark public Map<Integer, Integer> mapDiffOnly() { return Diff.diff(hashMapA, hashMapB); } @Benchmark public Map<Integer, Integer> sortedDiffOnly() { return Diff.diff(sortedMapA, sortedMapB); } public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() .include(DiffBenchmark.class.getSimpleName()) .build(); new Runner(opt).run(); } public static <K> Map<K, K> map(List<K> keysAndValues) { if (keysAndValues.size() % 2 != 0) { throw new IllegalArgumentException("Expected even keysAndValues.size()"); } Map<K, K> map = Maps.newHashMap(); for (int i=0; i < keysAndValues.size(); i+=2) { map.put(keysAndValues.get(i), keysAndValues.get(i+1)); } return map; } public static <K> SortedMap<K, K> sorted(List<K> keysAndValues) { if (keysAndValues.size() % 2 != 0) { throw new IllegalArgumentException("Expected even keysAndValues.size()"); } SortedMap<K, K> map = new TreeMap<>(); for (int i=0; i < keysAndValues.size(); i+=2) { map.put(keysAndValues.get(i), keysAndValues.get(i + 1)); } return map; } }