【问题标题】:Java Algorithm time measureJava算法时间度量
【发布时间】:2015-04-07 17:32:20
【问题描述】:

我的问题是,当我尝试准确测量我的算法执行时间时,一旦完成第一组测试,结果就会大不相同。

我有 7 个带有整数的文本文件,每个文本文件都有两个元素的幂。

24 = 16
28 = 256
212 = 4096
216 = 65536
220 = 1048576
222 = 4194304
224 = 16777216

我运行这些测试 X 次以获得执行时间。 一个测试用例被认为执行一次以上所有测试。而且我在不更改文本文件数据的情况下多次这样做。

为了测量我的算法执行时间,我使用 System.nanoTime();

        long start = System.nanoTime();
        (Algorithm)
        long elapsedNanoTime = System.nanoTime() - start;

但是,结果显示,在执行第一个测试用例后,开始测试 16 和 256 的下降幅度很大。

测试用例,迭代 1:

16 个元素需要 325336n
256 个元素需要 414861n
4096 个元素需要 2061728n
65536 个元素需要 21111426n
1048576 个元素需要 326898979n
4194304 个元素需要 1487154649n
16777216 个元素占用 6700800203n

测试用例,迭代 2:

16 个元素需要 2925n
256 个元素需要 36864n
4096 个元素需要 885603n
65536 个元素需要 15839933n
1048576 个元素需要 332000198n
4194304 个元素需要 1484967410n
16777216 个元素占用 6695675287n

测试用例,迭代 3:

16 个元素需要 2926n
256 个元素需要 35985n
4096 个元素需要 679635n
65536 个元素需要 15462227n
1048576 个元素占用 328179551n
4194304 个元素需要 1483733064n
16777216 个元素占用 6704160641n

如果我分别运行每个测试用例,“编译”程序只做 7 次测试,结果都像上面的迭代 1 一样。

那么有没有人知道为什么执行时间与第一个测试用例和其他测试用例不同?它是否与程序的初始化有关,或者内存已经在某处分配了数据?因为到目前为止,我不确定哪个执行时间数据是正确的。

提前致谢。

【问题讨论】:

  • google“java虚拟机预热”
  • I/O 非常昂贵——在编写 7 次测试时,您是在每次迭代中读取每个文本文件一次,还是只读取文件一次?
  • 运行每个测试 1000 次,丢弃太大的结果,计算平均值。
  • 感谢您的回答,现在我知道要寻找什么了。干杯

标签: java algorithm


【解决方案1】:

基准测试很难,您偶然发现了一种比较常见的麻烦事例; JIT compiler。 JVM 实际上负责编译您在运行时运行的一些代码,以便比编译器本身更进一步优化字节码。

描述如何确保您的基准测试准确超出了答案的范围(但有 many resources),但对于这个特定问题,您想要做的是多次运行您的基准测试(在同一个 JVM 中)并且丢弃前几次运行作为噪音。一旦基准测试运行了几次,JIT 就有机会为您优化代码,很可能不会在连续运行中进行更多优化。

【讨论】:

  • 谢谢,这正是我所需要的。干杯
【解决方案2】:

考虑使用jmh 作为微基准测试的框架。正如@dimo414 的回答中所指出的,在 JVM 上进行基准测试很困难。

【讨论】:

    猜你喜欢
    • 2012-02-25
    • 2022-12-04
    • 1970-01-01
    • 1970-01-01
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多