2009-06-23 104 views
3

我有一个用Java编写的解释器。我试图在解释器中测试各种优化的性能结果。要做到这一点,我解析代码,然后重复运行代码翻译,直到我得到5个运行,它们有一个很小的差距(在下面的时间0.1s),平均值被采取并打印。口译员不会出现I/O或随机性。如果我再次运行解释我得到不同的行进时间:Java性能不一致

91.8s 
95.7s 
93.8s 
97.6s 
94.6s 
94.6s 
107.4s 

我试图无济于事服务器和客户端虚拟机中,串行和并行GC,大表和Windows和Linux。这些是在1.6.0_14 JVM上。计算机没有进程在后台运行。所以我问什么可能会导致这些大的变化,或者我怎么能找出什么是?


实际的问题是由于程序必须迭代到固定点解决方案并将值存储在哈希集中导致的。散列值在运行之间不同,导致不同的排序,从而导致达到解决方案所需的迭代次数发生变化。

+0

堆设置为-Xms1024M -Xmx1024M。 – Molehill 2009-06-23 18:30:55

+0

你试过了什么? – akf 2009-06-23 18:32:47

回答

17

“挂钟时间”很少是衡量基准的好方法。一个现代操作系统极不可能“在后台运行没有进程” - 尽管你知道,它可能会将脏块缓冲区写入磁盘,因为它决定不存在其他争用。

相反,我建议使用ThreadMXBean来跟踪实际的CPU消耗。

+0

+1 JMX是要走的路。 – Tom 2009-06-23 18:35:14

+0

我可能已经略微夸大了“没有流程”。但是,任何正在运行的进程都不太可能发生干扰,并且只允许连续运行5次,只有0.1s。该机器有两个内核。 – Molehill 2009-06-23 18:42:25

1

垃圾回收可能是负责任的。尽管你的逻辑是相同的,但GC逻辑可能是在外部时钟/事件上安排的。

但我不太了解JVMs GC的实现。

5

你的变化看起来不大。在操作系统和JVM中,除了直接控制之外还有其他事情正在运行,这只是野兽的本质,你不可能得到确切的结果。

的事情,可能会影响运行时:

  • ,如果你的测试运行创建对象(可能会看不到你,库调用内,等等),那么你的重复可能引发GC

  • 不同GC算法,规格会有不同的反应,不同的增量gc阈值。你可以尝试在每次运行之前运行一个System.gc(),尽管当你调用JVM的时候JVM并不保证是GC(尽管它在我玩过它的时候总是有的).T根据测试的大小,以及你正在运行多少次迭代,这可能是一个令人不快的(并且几乎毫无用处)缓慢的事情。

  • 你在做什么样的随机测试吗?例如如果您正在测试整数,则值为< | 128 |在内存中可能会稍有不同。

最后,我不认为这是有可能得到一个确切的数字,可能是你能做的最好的是结果的集群围绕一个平均数字。

1

这似乎是一个重大的变化,我会尝试使用-verbosegc运行。

如果您的过程没有任何意义的IO,输出或网络,您应该能够获得小于一秒的变化。

我建议分析您的应用程序,如果您还没有这样做,极有可能会大幅节省。