【问题标题】:Decreasing execution time of identical consecutive runs of a Java program减少 Java 程序相同连续运行的执行时间
【发布时间】:2014-04-22 17:31:36
【问题描述】:

背景:我的团队正在开发一个 Java 程序,该程序接受文本作为输入,对其进行处理并显示结果。程序的每次运行都是无状态的,并且独立于其他运行。我们注意到,在同一文本上循环运行处理方法时,始终如一地,第一次运行完成的时间最长,接下来的运行时间越来越少,直到运行几十次后执行时间稳定一个远低于初始运行时间的值。

我尝试测试这是否是任何程序的普遍现象,并尝试运行以下具有嵌套循环的代码,并测量内部循环花费了多长时间:

String s = "abcefghijklmnopqrstuvwxyz";
int TIMES = 10;
int INNER_TIMES = 1000000; 
long count = 0;     
for (int i = 0; i < TIMES; i++) {       
    long start = System.currentTimeMillis();
    for (int j = 0; j < INNER_TIMES; j++) {
        List<String> list = new ArrayList<>();
        list.add(s);
    }
    count++;
    long end = System.currentTimeMillis();          
    double time = (end - start) / 1000.0;
    System.out.println(count + ": " + time + " seconds");
}

结果与我们在程序中注意到的相似:

1: 0.036 seconds
2: 0.018 seconds
3: 0.016 seconds
4: 0.009 seconds
5: 0.01 seconds
6: 0.009 seconds
7: 0.02 seconds
8: 0.014 seconds
9: 0.009 seconds
10: 0.01 seconds

我尝试运行了很多次,结果非常一致。内部循环的第一次运行总是需要大约 0.035-0.036 秒,从第 4 次开始(即使将 TIMES 增加到 1000)大约需要 0.008-0.01 秒(有一些例外)。

我和我的团队领导都对为什么会发生这种情况感到困惑。这是 Java 中的一个已知现象吗?一般在软件中?为什么软件在达到最佳性能之前似乎需要“预热”?

【问题讨论】:

  • 其他人大概可以给出详细的解释,但是我听说重复的代码会以某种方式被缓存,所以运行几次后运行速度更快。
  • 我认为,当 JIT 多次运行代码时,它会被编译,因此运行速度更快。我想这就是你在这里所经历的!

标签: java performance time


【解决方案1】:

这是 Java 应用程序的正常行为,这也意味着您不应该优化您的应用程序除非通过使用分析器确定存在瓶颈。 JVM 将通过在运行时为您的代码使用JIT (Just-In-Time) 编译来提高代码的性能。

您可以在此处找到有关 JIT 优化的更多信息:The Java HotSpot Performance Engine Architecture. Chapter 3. The Java HotSpot Compilers


除此之外,您正在对自己的代码进行非常简单的基准测试。我建议您阅读How do I write a correct micro-benchmark in Java? 以增强您的代码评估的当前结果。我还建议使用JMH,这是一个专门针对 Java 平台的微型基准测试框架。

【讨论】:

    【解决方案2】:

    这里可能有多种因素在起作用:

    • 第一次执行代码时,JIT 编译器可能会将 Java 字节码编译为本机代码,例如后续调用会更快(很可能会解释您看到的行为)
    • 本机代码可能被 CPU 缓存

    相信你可以关闭JIT (-Djava.compiler=NONE) 来验证第一个理论(虽然我之前从未关闭过JIT)

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-16
    • 2021-07-09
    • 2012-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-30
    相关资源
    最近更新 更多