總覽
有一個常見的誤解,因為JIT很智能,并且可以消除對象的同步,而該對象僅存在于不影響性能的方法中。
比較StringBuffer和StringBuilder的測試
這兩個類基本上做相同的事情,除了一個是同步的(StringBuffer)而另一個不是。 它也是一個類,通常在一種方法中用于構建String。 以下測試試圖確定彼此之間可以產生多少差異。
static String dontOptimiseAway = null;
static String[] words = new String[100000];public static void main(String... args) {for (int i = 0; i < words.length; i++)words[i] = Integer.toString(i);for (int i = 0; i < 10; i++) {dontOptimiseAway = testStringBuffer();dontOptimiseAway = testStringBuilder();}
}private static String testStringBuffer() {long start = System.nanoTime();StringBuffer sb = new StringBuffer();for (String word : words) {sb.append(word).append(',');}String s = sb.substring(0, sb.length() - 1);long time = System.nanoTime() - start;System.out.printf("StringBuffer: took %d ns per word%n", time / words.length);return s;
}private static String testStringBuilder() {long start = System.nanoTime();StringBuilder sb = new StringBuilder();for (String word : words) {sb.append(word).append(',');}String s = sb.substring(0, sb.length() - 1);long time = System.nanoTime() - start;System.out.printf("StringBuilder: took %d ns per word%n", time / words.length);return s;
}
最后使用Java 7 update 10使用-XX:+DoEscapeAnalysis
打印
StringBuffer: took 69 ns per word
StringBuilder: took 32 ns per word
StringBuffer: took 88 ns per word
StringBuilder: took 26 ns per word
StringBuffer: took 62 ns per word
StringBuilder: took 25 ns per word
用一百萬個單詞進行測試不會顯著改變結果。
結論
- 盡管使用同步的代價很小,但是它是可以衡量的,并且如果可以使用StringBuilder,則它是首選的,因為它在Javadocs中針對此類的狀態進行了說明。
- 從理論上講,可以優化同步,但是即使在簡單情況下也是如此。
參考: 可以優化同步嗎? 來自我們的JCG合作伙伴 Peter Lawrey,來自Vanilla Java博客。
翻譯自: https://www.javacodegeeks.com/2012/12/can-synchronization-be-optimised-away.html