performance-testing - Java 9的HashMap性能是否比Java 8低25%?

标签 performance-testing java-9 jmh

Note: This is not about a performance issue. I only observe a difference in performance I cannot explain / understand.



在对一些针对Java 9的新开发的代码进行基准测试时,我发现了一些奇怪的东西。一个非常简单的带有5个键的HashMap基准测试表明,Java 9比Java 8慢得多。这可以解释吗?还是我的(基准)代码是完全错误的?

代码:
@Fork(
    jvmArgsAppend = {"-Xmx512M", "-disablesystemassertions"}
)
public class JsonBenchmark {

    @State(Scope.Thread)
    public static class Data {

        final static Locale RUSSIAN = new Locale("ru");
        final static Locale DUTCH = new Locale("nl");

        final Map<Locale, String> hashmap = new HashMap<>();

        public Data() {
            hashmap.put(Locale.ENGLISH, "Flat flashing adjustable for flat angled roof with swivel");
            hashmap.put(Locale.FRENCH, "Solin pour toit plat inclinée");
            hashmap.put(Locale.GERMAN, "Flachdachkragen Flach Schrägdach");
            hashmap.put(DUTCH, "Plakplaat vlak/hellend dak inclusief glijschaal");
            hashmap.put(RUSSIAN, "Проход через плоскую кровлю регулир. для накл. кровли");
        }

    }

    @Benchmark
    public int bmHashMap(JsonBenchmark.Data data) {
        final Map<Locale, String> m = data.hashmap;
        int sum = 0;
        sum += m.get(Data.RUSSIAN).length();
        sum += m.get(Locale.FRENCH).length();
        sum += m.get(Data.DUTCH).length();
        sum += m.get(Locale.ENGLISH).length();
        sum += m.get(Locale.GERMAN).length();
        return sum;
    }    

}

结果:
  • Java 8_151:JsonBenchmark.bmHashMap thrpt 40 47948546.439±560763.711 ops/s
  • Java 9_181:JsonBenchmark.bmHashMap thrpt 40 34962904.479±276045.691 ops/s(-/-27%!)

  • 更新

    感谢您的回答和好评。
  • @Holger的建议。我的第一 react 是:这一定是解释。但是,如果仅对String#length()函数进行基准测试,则性能不会有显着差异。而且,当我仅对HashMap#get()方法(由@Eugene建议)进行基准测试时,仍然存在大约10-12%的差异。
  • @Eugene的建议。我更改了参数(更多的预热迭代,更多的内存),但是我无法重现您的结果。但是我将堆增加到了4G。但这不能解释差异,不是吗?
  • @Alan Bateman的建议。是的,这可以提高性能!但是,仍然相差约20%。
  • 最佳答案

    您正在测试的不仅仅是HashMap。您不仅在调用HashMap.get,而且在隐式调用Locale.hashCodeLocale.equals。此外,您正在调用String.length

    现在,这四种方法都可能改变了它们的性能特征,因此您将需要进行更多的测试才能推断出哪种方法表现出不同的性能。

    但是 HitTest 门的候选人是String.length。在Java 9中,String类不再使用char[]数组,而是使用byte[]数组对每个字符仅使用一个字节的拉丁语1字符串进行编码,从而大大减少了典型应用程序的内存占用量。但是,这意味着该长度不再总是与数组长度相同。因此,此操作的复杂性已更改。

    但请记住,您的结果在一个微基准测试中相差约77 ns。这还不足以估计对实际应用程序的影响…

    关于performance-testing - Java 9的HashMap性能是否比Java 8低25%?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46988645/

    相关文章:

    performance-testing - apache bench gnuplot 输出 - 列定义是什么?

    scala - 使用 Gatling 进行调试 - 如果状态为 500,则打印 ln

    java - 如何更改 Java 9 中的包装类初始化?

    compiler-errors - 使用 JDK 9 - 167 编译错误

    java - jmh 测试只能在 Hotspot 上运行吗?

    java - 使用 JMeter 测试 java 代码

    jmeter - 无法使用测试脚本记录器测试移动应用程序

    java - 对具有多版本实现的模块使用 jdeps,但根模块没有

    java - 为什么 .toString() 似乎修复了 StringBuilder 的 OutOfMemoryError 异常?

    java - 在 JMH 中对具有不同值的循环进行微基准测试