[英]Timing Confusion In Java
對於我從事的項目,我的任務是為兩種不同的搜索算法計時搜索時間:二進制搜索和順序搜索。 對於每種算法,我都應該記錄排序輸入和未排序輸入的時間。 當我比較排序輸入和未排序輸入的順序搜索的搜索時間時,遇到了一些奇怪的事情。 根據我最先排序的時間,搜索時間將明顯大於第二個時間。 因此,如果我先對排序的順序搜索,則比對未排序的順序搜索要花費更長的時間。
這對我來說沒有意義,是我困惑的根源。 由於要從輸入中獲取鍵,因此可以確保在數據輸入中找到搜索到的鍵(通過順序搜索)。
這是造成問題的代碼。 在這種情況下,seqOnUnsorted的搜索時間將比seqOnSorted的搜索時間長得多,而不應這樣。
public void sequentialSearchExperiment(){
seqOnUnsorted = sequentialSearchSet(keys, unsortedArray);
writeOutExperimentResults(seqOnUnsorted, seqOnUnsortedFilename, "Sequential Sort on Unsorted: ");
seqOnSorted = sequentialSearchSet(keys, sortedArray);
writeOutExperimentResults(seqOnSorted, seqOnSortedFilename, "Sequential Sort on Sorted: ");
}
sequenceSearchSet()方法如下:
public SearchStats[] sequentialSearchSet(int[] keys, int[] toSearch){
SearchStats[] stats = new SearchStats[keys.length];
for (int i = 0; i < keys.length; i++){
stats[i] = sequentialSearch(keys[i], toSearch);
}
return stats;
}
這是sequentialSearch():
public SearchStats sequentialSearch(int key, int[] toSearch){
long startTime = System.nanoTime(); // start timer
// step through array one-by-one until key found
for (int i = 0; i < toSearch.length; i++){
if (toSearch[i] == key){
return new SearchStats(key, i, System.nanoTime() - startTime);
}
}
// did not find key
return new SearchStats(key, -1, System.nanoTime() - startTime);
}
這是SearchStats構造函數:
public SearchStats(int keySearchedFor, int indexOfFound, long searchTime){
this.keySearchedFor = keySearchedFor;
this.indexOfFound = indexOfFound;
this.searchTime = searchTime;
}
如果我進行試運行,則平均搜索時間為:
sequential search on sorted: 21,080 ns
sequential search on unsorted: 2,137,465 ns
如您所見,由於我首先搜索未排序的內容,因此搜索時間明顯更長。 誰能解釋為什么會這樣? 而且,如何避免這種怪異?
這是由於VM“正在預熱”。 簡要總結一下,現代VM將通用代碼路徑編譯為本地代碼,並在運行時對其進行優化。 因此,圍繞循環的前幾次迭代,代碼被解析,並且比優化開始后的代碼要慢許多數量級。
在對Java進行性能分析時,這是一個常見的問題,通常的解決方案是在執行任何一個測得的測試之前, 對被測代碼進行數百萬次測試。
有關更多詳細信息和建議,您應該閱讀有缺陷的微基准解剖圖 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.