2009-06-23 100 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,輸出或網絡,您應該能夠獲得小於一秒的變化。

我建議分析您的應用程序,如果您還沒有這樣做,極有可能會大幅節省。