[英]Why StringBuilder append() faster than LinkedList add()?
[英]Why is this usage of concatentation in StringBuilder's constructor 100X faster than calling append()?
我偶然發現了一個與StringBuilder
的append
方法相關的奇怪性能問題。 我注意到似乎是一個愚蠢的錯誤 - 使用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.