2015-03-30 55 views
0

我的程序迭代給定的數據,我觀察到一個奇怪的行爲。算法處理的前幾個樣本表現出較慢的運行時間性能,但隨後的樣本和迭代運行幾乎一致(運行時間比前幾個樣本/迭代運行時間相對較低)。算法的第一次迭代慢但後續的迭代運行良好

這是爲什麼?我甚至試圖在迭代循環之外調用該函數作爲熱身函數調用,希望JVM能夠優化代碼,以便通過熱身函數調用來實現。

// warm up function call 
warpInfo = warp.getDTW(testSet.get(startIndex), trainSet.get(0), distFn, windowSize); 

this.startTime = System.currentTimeMillis(); 
for(int i=startIndex; i<endIndex; i++) { 
    for(int j=0; j<trainSet.size(); j++) { 
     train = trainSet.get(j); 
     instStartTime = System.currentTimeMillis(); 
     warpInfo = warp.getDTW(test, train, distFn, windowSize); 
     if(warpInfo.getWarpDistance()<bestDist) { 
      bestDist = warpInfo.getWarpDistance(); 
      classPredicted = train.getTSClass(); 
     } 
     instEndTime = System.currentTimeMillis(); 
     instProcessingTime = instEndTime - instStartTime; 
     // record timiing and results here 
    } 
    // record other information here 
} 
+1

你可以請你分享你的代碼與一些數據?沒有這些信息,我們甚至無法搜索答案。 – JFPicard 2015-03-30 17:51:08

+1

JVM優化需要的不僅僅是一次調用來實際執行優化...... JVM將該循環看作熱點並優化它 – 2015-03-30 17:51:37

+0

因此,您認爲在這種情況下預熱呼叫是無用的嗎?它不會對代碼優化產生任何影響? – 2015-03-30 18:03:25

回答

0

搜索後,我所遇到的幾個環節SO Answer to a similar questionthis Java performance comparison具有運行程序告訴JVM這許多函數調用之後編譯代碼時指定-XX:CompileThreshold=1的選項。另請參閱Oracle Page。 用我的程序執行測試運行後,我可以說它解決了這個問題。

**編輯:**根據Zarev的評論,我會說我錯了發佈這個答案。 CompieThreshold標誌只允許過早編譯代碼,因此它不會導致第一次迭代的運行時間更長,但實際上它可能會導致程序編譯時不考慮細節。

+1

這根本不是問題。這只是JIT的工作方式。使用'-XX:CompileThreshold = 1',你會造成更多的傷害(實際上並不好)。 – 2015-03-30 18:47:31

+0

然後是否有一個JVM開關儘快編譯字節碼,除了提到的那個將是更好的選擇。 – 2015-03-30 18:57:26

+0

快速編譯代碼毫無意義,因爲這樣可以防止JIT對其進行適當的配置和優化。您可以嘗試使用'-XX:+ TieredCompilation',它可以在幾個步驟中編譯您的代碼 – 2015-03-30 19:08:42