2017-09-21 55 views
0

我實現了一個標準的快速排序算法,並在幾次運行中對它進行測試,並將運行時間存儲在一個數組中。System.nanoTime()在QuickSort的幾次運行中返回連續遞減的時間,如何?

int max = 100; 
int runs = 1000; 
int[] arr = new int[max]; 
Long[] times = new Long[runs]; 

while(n < runs){ 
     for(int i =0 ; i<max; i++){ 
     arr[i]=(int)(Math.random()*99); 
     //arr[i] = i; 
     } 

     Long start = System.nanoTime(); 
     quicksortsimple(arr,0,max-1); 
     Long now = System.nanoTime(); 

     times[n++] = now-start; 
    } 

現在發生的事情是輸出的「倍」陣列大得多的值開始,並且逐漸減輕和第100指數(快速排序的100次)後它成爲一個位的常數,但該值小於十分之一的初始2-3值。 n = 1000返回的平均值在程序的幾個符文中是相同的。

即使我初始化數組爲已經排序(註釋行)同樣的事情發生,雖然需要更多的平均時間(因爲它應該)。

但是,對於同一陣列中的相同算法,這不應該返回這種不同的運行時間。什麼樣的減少模式表明,如果有的話?

+1

https://stackoverflow.com/a/11227902/4467208 –

+1

它表明你的基準是有缺陷的:https://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro- benchmark-in-java – Kayaman

+0

只要System.nanoTime()返回的數字在每次迭代時都不會變小(所以我們不必處理時間旅行),似乎有很多可能的解釋。我建議只在測量值爲常數時才使用測量... – mumpitz

回答

0

(下面的解釋不準確到最後的細節,但足以明白這是怎麼回事)

在開始的時候,你的JRE在解釋模式下(慢),運行程序,直到其熱點引擎檢測到排序值得加速並創建本地編譯的翻譯,然後使用該翻譯,並且運行速度比第一次迭代中的解釋代碼快得多。

+0

所以應該有一個「點」或JRE改變模式的一些離散點。但是,我使用1000的times []數組,並且結果「持續」下降,其間有些起伏。這是什麼意思?你能否詳細說明可能發生的事情?這似乎很有趣。 –

+0

熱點編譯不是影響性能的唯一因素,但通常是最突出的一個。優化不一定發生在一個步驟中。例如。除了'quicksortsimple()'方法之外,還有'Math.random()'經常被調用,並且有你的外部循環。它們中的每一個都是獨立本地編譯的候選對象,最後Hotspot引擎甚至可以將它們全部內聯到一個本地代碼中。當Hotspot等後臺任務不再消耗CPU時,處理器的緩存命中率就會更高,等等...... –