簡體   English   中英

測量執行時間的常用技術提供不同的值 (java)

[英]common techniques to measure execution time provide different values (java)

我試圖在不同類型的集合上測量不同操作的時間並想比較它們,但我得到的值在相同類型的集合上有很大不同,比如因子 1000。我使用我在這里讀到的常用技術: 如何在 Java 中為方法的執行計時?

我比較了 Hashset、TreeSet 和 LinkedHashSet。 我用 1 000 000 個整數填充集合,使用方法 contains() 並遍歷集合。 我測量了每個操作的時間,數值相差很大。 所以我用相同類型的新集合第二次這樣做了,我得到的執行時間似乎不合法。

相同類型的集合需要一次 1400 毫秒然后 300 毫秒才能被填充。 這是為什么?

這是一個代碼示例,它可能會使我的意思更清楚:

    public static void main(String[] args){

    HashSet<Integer> firstHashSet = new HashSet<>(predefinedSize);
    HashSet<Integer> secondHashSet = new HashSet<>(predefinedSize);
    LinkedHashSet<Integer> firstLinkedHashSet = new LinkedHashSet<>(predefinedSize);
    LinkedHashSet<Integer> secondLinkedHashSet = new LinkedHashSet<>(predefinedSize);
    TreeSet<Integer> firstTreeSet = new TreeSet<>();
    TreeSet<Integer> secondTreeSet = new TreeSet<>();
    int x = 9432;
    System.out.println("filling hashSet:        <" + fillSet(firstHashSet) + "> milliSeconds");
    System.out.println("filling linkedSet:      <" + fillSet(firstLinkedHashSet) + "> milliSeconds");
    System.out.println("filling treeSet:        <" + fillSet(firstTreeSet) + "> milliSeconds");
    System.out.println("-------------------------------------------------------------");
    System.out.println("filling hashSet:        <" + fillSet(secondHashSet) + "> milliSeconds");
    System.out.println("filling linkedSet:      <" + fillSet(secondLinkedHashSet) + "> milliSeconds");
    System.out.println("filling treeSet:        <" + fillSet(secondTreeSet) + "> milliSeconds");

這是我的一個圓角的樣子:

private static int size = 1000000;
private static int predefinedSize = 2000000;

public static double fillSet(LinkedHashSet<Integer> myHashSet){
    double timeStart = System.nanoTime();
    for(int i=0; i<size; i++){
        myHashSet.add(i);
    }
    double time = (System.nanoTime() - timeStart)/ Math.pow(10, 6);
    return time;
}

輸出是這樣的:

filling hashSet:        <52.14022> milliSeconds
filling linkedSet:      <95.599435> milliSeconds
filling treeSet:        <2172.773956> milliSeconds
-------------------------------------------------------------
filling hashSet:        <59.096929> milliSeconds
filling linkedSet:      <1006.638126> milliSeconds
filling treeSet:        <241.36395> milliSeconds

你看到輸出差異很大,我認為這取決於我電腦的計算能力,但我沒有在后台運行任何其他程序。 有人可以給我一個解釋和/或解決方案嗎?

正如@kan 的評論所提到的,使用系統計時器並執行一百萬次將提供截然不同的結果。 您正在尋找的是一個微基准:

如何在 Java 中編寫正確的微基准測試?

至於您的時間安排無處不在的原因,您必須閱讀有關計算機體系結構和 Java JVM 的信息。 一些可能性:

  • 處理器中的動態時鍾速度技術https://electronics.stackexchange.com/questions/62353/how-can-a-cpu-dynamically-change-its-clock-frequency - 您可以通過改變 CPU 的能力來消除這種可能性它的時鍾速度關閉。
  • 您的集合有 100 萬個 Int 類型元素,即 4 MiB。 考慮到非服務器 CPU 將具有 1 到 8 MiB 的緩存,該大小幾乎是它是否適合您的處理器緩存的極限。 如果在一次執行中您的 100 萬個元素在緩存中停留的時間比在另一次執行中的時間長,您將獲得截然不同的執行時間。 您可以通過使您的集合小到絕對適合緩存(最多數十 KB)或大到根本無法使用緩存(可能是 100 兆字節)來消除這種可能性。
  • 您可能沒有運行任何其他應用程序,但仍有其他東西在您的計算機后台運行。 (防病毒、更新服務、與操作系統內部工作相關的 10-20 個其他任務)
  • Java 虛擬機的行為可能有所不同(我對此不太確定,因為我不是 JIT、GC 和其他可能影響執行時間的東西的內部工作的專家)。 微基准庫將在很大程度上消除這種可能的差異。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM