Я запускаю задачу JMH для проверки производительности ConcurrentHashMap и HashMap с функцией get, но результат отличается от добавления StackProfile или нет, почему?
это базовый код, и не нужно запускать StackProfile
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Warmup(iterations = 5, time = 5000, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 5, time = 5000, timeUnit = TimeUnit.MILLISECONDS)
public class MapGetTest {
private static final int DISTINCT_KEYS = 200_000;
private static final String KEY = "the_key_to_use";
private static final String VALUE = "the quick brown fox jumped over the lazy dog the olympics are about to start";
@State(Scope.Benchmark)
public static class HashMapBenchmark {
private final String[] keys = new String[DISTINCT_KEYS];
private final String[] values = new String[DISTINCT_KEYS];
Map<String, String> map;
int counter;
@Setup(Level.Trial)
public void setUp() {
map = new HashMap<>(1334);
for (int i = 0; i < DISTINCT_KEYS; ++i) {
keys[i] = KEY + i;
values[i] = VALUE + i;
map.put(keys[i] + i, values[i]);
}
}
}
@Benchmark
public String hashMapGet(HashMapBenchmark benchmark) {
benchmark.counter++;
return benchmark.map.get(benchmark.keys[benchmark.counter % DISTINCT_KEYS]);
}
@State(Scope.Benchmark)
public static class ConcurrentBenchmark {
private final String[] keys = new String[DISTINCT_KEYS];
private final String[] values = new String[DISTINCT_KEYS];
Map<String, String> map;
int counter;
@Setup(Level.Trial)
public void setUp() {
map = new ConcurrentHashMap<>(1334);
for (int i = 0; i < DISTINCT_KEYS; ++i) {
keys[i] = KEY + i;
values[i] = VALUE + i;
map.put(keys[i] + i, values[i]);
}
}
}
@Benchmark
public String concurrentHashMapGet(ConcurrentBenchmark benchmark) {
benchmark.counter++;
return benchmark.map.get(benchmark.keys[benchmark.counter % DISTINCT_KEYS]);
}
public static void main(String[] args) throws RunnerException {
Options options = new OptionsBuilder().include(MapGetTest.class.getSimpleName())
.threads(1).forks(1).build();
new Runner(options).run();
}
}
the result is :
1. MapGetTest.concurrentHashMapGet 15192.712 ± 2643.952 ops/ms
2. MapGetTest.hashMapGet 18939.627 ± 559.116 ops/ms
Когда я запускаю со StackProfile:
Options options = new OptionsBuilder().include(MapGetTest.class.getSimpleName())
.threads(1).forks(1).addProfiler(StackProfiler.class).build();
new Runner(options).run();
результат:
1. MapGetTest.concurrentHashMapGet 21315.406 ± 7938.457 ops/ms
2. MapGetTest.hashMapGet 17675.858 ± 600.257 ops/ms
Моя среда: версия JMH: 1.21, версия виртуальной машины: JDK 1.8.0_181, 64-разрядная серверная виртуальная машина Java HotSpot (TM), 25.181-b13