我有一个用Java编写的解释器。我试图在解释器中测试各种优化的性能结果。为此,我解析代码,然后在代码上重复运行解释器,这一直持续到我得到5次运行,这些运行的差异非常小(下面的时间为0.1秒),取平均值并打印。解释器中没有I / O或随机性。如果我再次运行解释器,我会得到不同的运行时间:
91.8s
95.7s
93.8s
97.6s
94.6s
94.6s
107.4s
我试图无法使用服务器和客户端VM,串行和并行gc,大型表和窗口以及linux。这些是在1.6.0_14 JVM上。计算机没有在后台运行的进程。所以我问可能导致这些大变化的原因,或者我怎样才能找出它是什么?
由于程序必须迭代到定点解决方案并且值存储在散列集中,因此导致了实际问题。运行之间的散列值不同,导致不同的排序,从而导致达到解决方案所需的迭代量发生变化。
答案 0 :(得分:17)
“挂钟时间”很少是基准测试的良好衡量标准。现代操作系统极不可能“[没有在后台运行进程” - - 众所周知,它可能是将脏块缓冲区写入磁盘,因为它确定没有其他争用。
相反,我建议使用ThreadMXBean来跟踪实际的CPU消耗。
答案 1 :(得分:5)
你的变化看起来不那么大。这只是野兽的本质,在操作系统和JVM中,还有其他东西在你的直接控制之外运行,你不可能得到确切的结果。
可能影响运行时的事情:
如果您的测试运行正在创建对象(可能对您不可见,在库调用中等),那么您的重复可能会触发GC
不同的GC算法,规范会有不同的反应,增量gc的阈值不同。您可以尝试在每次运行之前运行System.gc(),尽管在您调用它时不能保证JVM(虽然它总是在我使用它时).T根据您的测试大小,你正在运行多少次迭代,这可能是一件令人不快(而且几乎毫无用处)慢的事情。
您是否在测试中进行任何类型的随机化?例如如果你正在测试整数,那么值< | 128 |可能在内存中处理稍有不同。
最终,我认为没有可能得到一个确切的数字,可能你能做的最好的是围绕结果集的平均数字。
答案 2 :(得分:1)
垃圾回收可能是负责任的。即使您的逻辑相同,也可能是GC逻辑正在外部时钟/事件上进行调度。
但我对JVMs GC的实现知之甚少。
答案 3 :(得分:1)
这对我来说似乎是一个很大的变化,我会尝试使用-verbosegc运行。
如果您的流程没有任何重要的IO,输出或网络,您应该能够将变化推迟到不到一秒钟。
我建议您对应用程序进行分析,如果您还没有这样做,很可能会有很大的节省。