我正在运行一个JMH任务来测试ConcurrentHashMap和HashMap的“获取”功能性能,但是结果与添加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,VM版本:JDK 1.8.0_181,Java HotSpot(TM)64位服务器VM,25.181-b13