Когда я запускаю задачу jmh с помощью «StackProfiler», оценка ConcurrentHashMap лучше? - PullRequest
0 голосов
/ 28 марта 2019

Я запускаю задачу 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

...