簡體   English   中英

為什么在StringBuilder的構造函數100X中使用concatentation比調用append()更快?

[英]Why is this usage of concatentation in StringBuilder's constructor 100X faster than calling append()?

我偶然發現了一個與StringBuilderappend方法相關的奇怪性能問題。 我注意到似乎是一個愚蠢的錯誤 - 使用StringBuilder構造函數時的字符串連接(這甚至在NetBeans IDE中顯示為警告)。

版本1

int hash = -1;     //lazily computed, also present in Version 2
int blockID = ...  //0 to 1000, also present in Version 2
int threadID = ... //0 to 1000, also present in Version 2
boolean hashed = false;       //also present in Version 2

@Override
public int hashCode(){
    if(!hashed){
        StringBuilder s = new StringBuilder(blockID+":"+threadID);
        hash = s.toString().hashCode();
        hashed= true;
    }

    return hash;
}

在運行時期間創建了數百萬個這樣的對象,所以我想通過進行以下更改,它會提供一些加速:

版本2

@Override
public int hashCode(){
    if(!hashed){
        StringBuilder s = new StringBuilder(blockID);
        s.append(":");
        s.append(threadID);
        hash = s.toString().hashCode();
        hashed = true;
    }

    return hash;
}

錯誤! 事實證明,版本2實際上比版本1慢100倍。為什么???

附加信息

我正在編譯Java 6(客戶需求),我正在使用Oracle的JVM。

我的性能測試涉及創建一百萬個這些對象並將它們放入HashMap中。 使用版本1需要半秒鍾,但使用版本2執行此操作幾乎需要50秒。

因為您無意中設置了StringBuilder的初始容量,而不是將blockID附加到它。 請參閱此處的構造函數文檔

public StringBuilder(int capacity)

構造一個字符串構建器,其中沒有字符和capacity參數指定的初始容量。

試試這個:

StringBuilder s = new StringBuilder(9);
s.append(blockID).append(':').append(threadID);

您需要檢查您的測試,因為您的第一個案例實際上正在進行。

public int hashCode(){
    if(!hashed){
        StringBuilder s = new StringBuilder(
                  new StringBuilder(blockID).append(":").append(threadID).toString());
        hash = s.toString().hashCode();
        hashed= true;
    }

    return hash;
}

換句話說,它在第二種情況下做的更多,所以它會更慢。

簡而言之,我懷疑你的測試是錯誤的,而不是你的表現更好。

暫無
暫無

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

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