首页 > 解决方案 > Java 11 字符串连接性能与 Java 8

问题描述

有谁知道为什么我在 Java 8 和 Java 11 上运行此代码时会获得如此不同的性能?

在不使用任何运行时标志的情况下,与 Java 8 相比,此代码在 Java 11 下的运行速度似乎要慢得多。

import java.util.Date;

public class PerformanceExperiment {
    public static volatile String s = "";

    public static void main(String[] args)
    {                         
        System.out.println("Starting performance test");
        String s1 = "STRING ONE";
        String s2 = "STRING TWO";
        long now1 = (new Date()).getTime();
        for (long i = 0; i < 1_000_000_00; i++)
        {
            s = "abc " + s1 + " def " + s2;
        }
        long now2 = (new Date()).getTime();
        System.out.println("initial block took " + (now2 - now1) + "ms");
        for (long i = 0; i < 4_000_000_00; i++)
        {
            s = "abc " + s1 + " def " + s2;
        }
        long now3 = (new Date()).getTime();
        System.out.println("Main block took " + (now3 - now2) + "ms");
    }
}

我尝试了许多命令行标志,但没有找到任何与 Java 8 性能相匹配的东西。

我只在 Windows 上对此进行了测试,因此它在其他操作系统上的行为可能会有所不同。

标签: javastringperformanceconcatenation

解决方案


我将您的应用修改为

  1. 使用System.nanoTime()代替以new Date()获得更高的精度(有关更多信息,请参阅此答案:https ://stackoverflow.com/a/1776053/963076 )。
  2. 使用 Netbeans 分析器。
  3. 循环 10 次迭代

将 Netbeans 8.2 与 JDK 8 v181 一起使用:

Starting performance test 0
initial block took 3147ms
Main block took 9469ms
Starting performance test 1
initial block took 2398ms
Main block took 9601ms
Starting performance test 2
initial block took 2463ms
Main block took 9671ms
Starting performance test 3
initial block took 2464ms
Main block took 9565ms
Starting performance test 4
initial block took 2410ms
Main block took 9672ms
Starting performance test 5
initial block took 2418ms
Main block took 9598ms
Starting performance test 6
initial block took 2384ms
Main block took 9733ms
Starting performance test 7
initial block took 2402ms
Main block took 9610ms
Starting performance test 8
initial block took 2509ms
Main block took 11222ms
Starting performance test 9
initial block took 2455ms
Main block took 10661ms

探查器显示了这个遥测数据:

在此处输入图像描述

对于使用 JDK 11.0.2 的 Netbeans 10.0:

Starting performance test 0
initial block took 3760ms
Main block took 15056ms
Starting performance test 1
initial block took 3734ms
Main block took 14602ms
Starting performance test 2
initial block took 3615ms
Main block took 14762ms
Starting performance test 3
initial block took 3748ms
Main block took 14534ms
Starting performance test 4
initial block took 3628ms
Main block took 14759ms
Starting performance test 5
initial block took 3625ms
Main block took 14959ms
Starting performance test 6
initial block took 3987ms
Main block took 14967ms
Starting performance test 7
initial block took 3803ms
Main block took 14701ms
Starting performance test 8
initial block took 3599ms
Main block took 14762ms
Starting performance test 9
initial block took 3627ms
Main block took 14434ms

在此处输入图像描述

我的结论是:JDK 11 正在做更多的工作来提高内存效率。请注意,垃圾收集器中“幸存代”的数量在 JDK11 中要少得多,而且内存使用量在使用率和波动性方面也明显减少。权衡似乎是在速度上,但速度上的差异小于内存使用的差异。


推荐阅读