обзор
Существует распространенное заблуждение, что поскольку JIT является разумным, и синхронизация может быть исключена для объекта, который является только локальным для метода, который не оказывает влияния на производительность.
Тест, сравнивающий StringBuffer и StringBuilder
Эти два класса делают в основном одно и то же, за исключением того, что один синхронизируется (StringBuffer), а другой — нет. Это также класс, который часто используется в одном методе для создания строки. В следующем тесте делается попытка определить, какую разницу могут использовать друг друга.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
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;} |
в конце печатает с -XX:+DoEscapeAnalysis с использованием Java 7 update 10
|
1
2
3
4
5
6
|
StringBuffer: took 69 ns per wordStringBuilder: took 32 ns per wordStringBuffer: took 88 ns per wordStringBuilder: took 26 ns per wordStringBuffer: took 62 ns per wordStringBuilder: took 25 ns per word |
Тестирование с миллионом слов существенно не меняет результаты.
Вывод
- Хотя стоимость использования синхронизации невелика, она поддается измерению, и если вы можете использовать StringBuilder, она предпочтительнее, так как она указана в Javadocs для этого класса.
- Теоретически синхронизация может быть оптимизирована, но даже в простых случаях это еще не произошло.
Справка: можно ли оптимизировать синхронизацию? от нашего партнера JCG Питера Лоури из блога Vanilla Java .