【问题标题】:Java execution time doesn't add upJava 执行时间不加起来
【发布时间】:2021-04-26 11:05:48
【问题描述】:

我有以下主要功能:

public static void main(String[] args) {
        
        int times = 100;
        
        double startTime = System.nanoTime();
        for (int a = 1; a <= times; a++) {
            BTree<Integer> testTree = new BTree<Integer>(1,3); // Creates BTree with root 1 and degree T 3
            for (int i = 2; i <= 500; i++) {
                testTree.BTreeInsert(i); // We insert up to 500 keys.
            }
        }
        double stopTime = System.nanoTime();
        
        System.out.println("Time: " + (((stopTime-startTime) / 1000000 / times)) + "ms");
    }

我在这里尝试做的是测量将新密钥插入 B 树的执行时间最多 500 次。问题是我得到的时间测量有点小,所以我的老师告诉我要循环多次。

但是,我得到的结果似乎并不相加,使用此配置程序返回Time: 0.167(..) ms,同时使用times = 1,代码返回Time: 2.1401 ms.

我觉得我错过了一些重要的事情,但我不知道是什么。

【问题讨论】:

  • BTree 定义为什么?您确定它没有错误并且编译器优化器没有妨碍吗?
  • 嗯,打印出来的时候你把时间除以times。所以这告诉你,当你连续多次这样做时,它会更快。这是有道理的,因为准备 JVM 有很多开销
  • @CharlieArmstrong ,我明白了。我不知道如何看待它,因为我试图在没有任何开销的情况下找到它的执行时间,但至少现在我知道发生了什么。谢谢!
  • @Sanzor 测试执行时间是一项很难正确完成的任务,尤其是在 Java 这样的高级语言中。如果你有兴趣,here's 是一个更难诊断的例子。您可以使用几个 Java 库,它们将帮助您尽可能减少这种干扰。但是,如果这是一个学校项目,我只能想象您的老师正计划对此提出意见,他们可能希望您找到这种差异。

标签: java


【解决方案1】:

这是因为 JVM 看到循环运行多次(分析)并使用优化编译器(如果那是 HotSpot JVM,则为 C1 和 C2)。如果您使用-XX:+PrintCompilation(如java -XX:+PrintCompilation ClassName)运行您的课程,您可以看到在带有500 试验的版本中,编译了更多方法-例如,我的OpenJDK 15.0.1 java 编译ArrayList::add 多次,与C1及之后,C2(第三列中的2和3是C1的不同优化级别,4是C2):

 45   48       3       java.util.ArrayList::add (25 bytes)
 46   51       4       java.lang.Number::<init> (5 bytes)
 46   49       2       java.util.ArrayList::add (23 bytes)
 47   46       3       java.lang.Number::<init> (5 bytes)   made not entrant
 47   52       4       java.util.ArrayList::add (25 bytes)

因此,当运行 500 次迭代的循环时,经过多次迭代后,它使用已编译且高度优化的代码,而单次迭代版本将其留给解释器,速度较慢。

另外,我建议您研究一下JMH,这是一个用来做你想做的事情的工具——微基准测试。

【讨论】:

    【解决方案2】:

    另外请记住,“B-tree [数据结构] 本身”也是这张时序图中的通配符……而且它必然会受到“数据本身”的影响。 "每当您在这种结构中插入或删除记录时,执行此操作所需的时间可能会有很大差异!

    B-tree 索引数据结构旨在优化按键检索项。因此,他们寻求维护“相当平衡”的数据结构,以便检索时间随着时间的推移保持相当一致。好吧,他们为此付出的代价是插入和删除过程——据推测,这些过程发生的频率远低于检索。

    【讨论】:

      猜你喜欢
      • 2012-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-15
      • 2011-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多