我的问题是,当我试图准确测量我的算法执行时间时,一旦完成第一组测试,结果会有很大差异。
我有7个带有整数的文本文件,每个文本文件都有两个元素。
2 4 = 16
2 8 = 256
2 12 = 4096
2 16 = 65536
2 20 = 1048576
2 22 = 4194304
2 24 = 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中。
那么有没有人能够了解为什么执行时间与第一个测试用例和其他测试用例不同?它是否与程序的初始化有关,或者内存已经在某处分配了数据?因为到目前为止,我不确定哪个执行时间数据是正确的。
提前致谢。
答案 0 :(得分:1)
基准测试很难,你偶然发现了一个比较常见的麻烦案例; JIT compiler。 JVM实际上负责编译你运行作为其运行的一些代码,以便比编译器本身希望的那样优化字节码。
描述如何确保基准测试的准确性超出了答案的范围(但有many resources)但是对于这个特定问题,您要做的是多次运行基准测试(在同一个JVM中)并将前几次运行作为噪音丢弃。一旦基准测试运行了几次,JIT将有机会为您优化代码,并且可能在连续运行中不会进行更多优化。
答案 1 :(得分:0)
考虑使用jmh作为微观基准的框架。正如在@dimo414的回答中指出的那样,JVM上的基准测试很难。