RFR: 8293630: Simplify TreeMap.get() with Comparator.naturalOrder() [v4]
Сергей Цыпанов
duke at openjdk.org
Wed Nov 9 16:00:20 UTC 2022
On Mon, 17 Oct 2022 10:19:26 GMT, Сергей Цыпанов <duke at openjdk.org> wrote:
>> We can use `Comparator.naturalOrder()` for cases when a `TreeMap` instance is constructed without comparator. This allows to squash two branches in `TreeMap.get()` into one.
>>
>> P.S. I think the comment of `TreeMap.getEntryUsingComparator()` is outdated. Should we also change it?
>
> Сергей Цыпанов has updated the pull request incrementally with one additional commit since the last revision:
>
> 8293630: Inline natural()
For the benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 15, time = 2, timeUnit = TimeUnit.SECONDS)
@Fork(10)
@State(Scope.Thread)
public class TreeMapGet {
@Param({"10", "100", "1000", "10000"})
public int size;
@Param({"true", "false"})
public boolean comparator;
private TreeMap<Integer, Integer> map;
private Integer[] keys;
@Setup(Level.Iteration)
public void setUp() {
map = comparator ? new TreeMap<>(Comparator.reverseOrder()) : new TreeMap<>();
keys = IntStream.range(0, size).boxed().toArray(Integer[]::new);
Collections.reverse(Arrays.asList(keys));
for (Integer key : keys) {
map.put(key, key);
}
}
@Benchmark
public void get(Blackhole bh) {
var keys = this.keys;
var map = this.map;
for (Integer key : keys) {
bh.consume(map.get(key));
}
}
}
I got these results:
baseline
Benchmark (comparator) (size) Mode Cnt Score Error Units
TreeMapGet.get true 10 avgt 150 69.170 ± 0.886 ns/op
TreeMapGet.get true 100 avgt 150 1369.488 ± 36.312 ns/op
TreeMapGet.get true 1000 avgt 150 31462.583 ± 261.650 ns/op
TreeMapGet.get true 10000 avgt 150 490948.456 ± 3395.402 ns/op
TreeMapGet.get false 10 avgt 150 69.625 ± 0.975 ns/op
TreeMapGet.get false 100 avgt 150 1076.163 ± 30.976 ns/op
TreeMapGet.get false 1000 avgt 150 36528.309 ± 140.245 ns/op
TreeMapGet.get false 10000 avgt 150 422948.634 ± 976.892 ns/op
patch
Benchmark (comparator) (size) Mode Cnt Score Error Units
TreeMapGet.get true 10 avgt 150 68.814 ± 1.221 ns/op
TreeMapGet.get true 100 avgt 150 1280.799 ± 34.319 ns/op
TreeMapGet.get true 1000 avgt 150 31530.447 ± 329.406 ns/op
TreeMapGet.get true 10000 avgt 150 435109.171 ± 1807.717 ns/op
TreeMapGet.get false 10 avgt 150 65.646 ± 0.124 ns/op
TreeMapGet.get false 100 avgt 150 1083.535 ± 23.545 ns/op
TreeMapGet.get false 1000 avgt 150 36299.345 ± 494.126 ns/op
TreeMapGet.get false 10000 avgt 150 444266.085 ± 2315.616 ns/op
For benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 15, time = 2, timeUnit = TimeUnit.SECONDS)
@Fork(10)
@State(Scope.Thread)
public class TreeMapEntrySetStream {
@Param({"10", "100", "1000", "10000"})
public int size;
@Param({"true", "false"})
public boolean comparator;
private TreeMap<Integer, Integer> map;
@Setup(Level.Iteration)
public void setUp() {
map = comparator ? new TreeMap<>(Comparator.reverseOrder()) : new TreeMap<>();
var keys = IntStream.range(0, size).boxed().toArray(Integer[]::new);
Collections.reverse(Arrays.asList(keys));
for (Integer key : keys) {
map.put(key, key);
}
}
@Benchmark
public void get(Blackhole bh) {
var map = this.map;
map.entrySet().stream().forEach(bh::consume);
}
}
results are the following:
baseline
Benchmark (comparator) (size) Mode Cnt Score Error Units
TreeMapEntrySetStream.get true 10 avgt 150 32.714 ± 0.117 ns/op
TreeMapEntrySetStream.get true 100 avgt 150 271.825 ± 0.596 ns/op
TreeMapEntrySetStream.get true 1000 avgt 150 3267.876 ± 42.650 ns/op
TreeMapEntrySetStream.get true 10000 avgt 150 43207.384 ± 457.110 ns/op
TreeMapEntrySetStream.get false 10 avgt 150 30.863 ± 0.071 ns/op
TreeMapEntrySetStream.get false 100 avgt 150 259.394 ± 0.493 ns/op
TreeMapEntrySetStream.get false 1000 avgt 150 3362.446 ± 44.108 ns/op
TreeMapEntrySetStream.get false 10000 avgt 150 42190.313 ± 421.604 ns/op
patch
Benchmark (comparator) (size) Mode Cnt Score Error Units
TreeMapEntrySetStream.get true 10 avgt 150 30.856 ± 0.112 ns/op
TreeMapEntrySetStream.get true 100 avgt 150 270.719 ± 0.504 ns/op
TreeMapEntrySetStream.get true 1000 avgt 150 3278.241 ± 41.304 ns/op
TreeMapEntrySetStream.get true 10000 avgt 150 42549.518 ± 427.607 ns/op
TreeMapEntrySetStream.get false 10 avgt 150 31.780 ± 0.092 ns/op
TreeMapEntrySetStream.get false 100 avgt 150 252.551 ± 0.414 ns/op
TreeMapEntrySetStream.get false 1000 avgt 150 3359.962 ± 44.337 ns/op
TreeMapEntrySetStream.get false 10000 avgt 150 41613.570 ± 381.721 ns/op
-------------
PR: https://git.openjdk.org/jdk/pull/9901
More information about the core-libs-dev
mailing list