总览
有一个常见的误解,因为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