Разница между объединением строк и использованием StringBuffer append - PullRequest
0 голосов
/ 22 февраля 2011

Статический контент был жестко запрограммирован в файлах Java, например:

String s = "<span class=\"className\">StaticContent</span>";

Он должен быть выведен с помощью объектов ResourceBundle.

Простой способ сделать это:

String s = "<span class=\"className\">" + 
           ResourceBundleObject.getString("StaticContent.key") + "</span>";

Второй метод использует объект StringBuilder:

StringBuilder sb = new StringBuilder();
sb.append("<span class=\"className\">");
sb.append(ResourceBundleObject.getString("StaticContent.key"));
sb.append("</span>");
String s = sb.toString();

Имеет ли второй метод преимущество перед первым (с точки зрения потребляемых ресурсов)?

Первый метод проще использовать, так как он требует меньше редактирования.

Ответы [ 5 ]

4 голосов
/ 22 февраля 2011

Одна конкатенация строк создает новый объект String:

"a" + "b" + "c" + "d"      // 4 Strings
"ab"                       // 1 String
"abc"                      // 1 String
"abcd"                     // 1 String
                           // 7 String instances in total (& in theory / worst case)

StringBuilder создает меньше объектов:

StringBuilder sb = new StringBuilder("a").append("b").append("c").append("d")
                           // 4 Strings, 1 StringBuilder 
                               = 5 objects (in theory/worst case)

Но компилятор знает об этой проблеме, и если вы посмотрите на байт-код файлов классов, достаточно часто вы увидите, что конкатенации строк были заменены на StringBuilder и добавлены. Имея это в виду, вы можете сосредоточиться на читабельном коде и предоставить его компилятору для поиска наиболее производительного решения.

Лично я использую выделенный StringBuilder только в том случае, если мне нужно собрать большие строки (например, исходный код Java или HTML-страницы) или если я использую циклы для сборки строк, например:

 String result = "";
 for (int i = 0; i < 100; i++)
   result += ".";    // Ouch - this should be done with StringBuilder
2 голосов
/ 22 февраля 2011

В этом случае нет никакого преимущества в производительности при использовании явного StringBuilder.

JLS утверждает, что компилятору Java разрешено компилировать последовательность подвыражений конкатенации строк в эквивалентное создание временного StringBuilder и последовательности вызовов append. В этом случае оптимизация работает, и компилятор генерирует байт-коды, которые практически совпадают с байт-кодами, которые вы получили бы, если бы использовали StringBuilder самостоятельно. Другими словами, единственный чистый эффект от использования StringBuilder - усложнение чтения кода.

Вы можете получить преимущество в производительности только при явном использовании StringBuilder, если ваш код выполняет конкатенацию в цикле. Однако, если вы строите длинные строки таким образом, разница в производительности может быть значительной.

1 голос
/ 22 февраля 2011

Строки являются неизменяемыми - как только они созданы, они не могут быть изменены.

Так что, если вы делаете string1 + string2, строка2 просто не копируется в конец строки1 - создается новая строка, которая содержит сцепленныестрока.Если вы выполните всю последовательность этих операций, это может стать очень дорогостоящим.

Следует заметить, однако, что под покровами JVM преобразует код цепочки строк (с помощью +) в последовательность вызовов string Builder.Так что на самом деле ваши два фрагмента должны компилироваться в байт-код smae (или очень похожий).

Как всегда, тестируйте и измеряйте, если хотите оптимальную производительность.

1 голос
/ 22 февраля 2011
 1. First One will create three Instance.  // "" will create 2 temp instance , concat using + another instance 
 2. Second One wil create One Instance.

 - the String class is an immutable class.
 - It will never really change internally. When you use the operator
   it actually  do not change the string itself, but rather return a
   new String.

 - StringBuilder is more efficient as it is designed with no thread-safety in mind.
 - Will appends to it the previous value of the string.
 - if you are building long strings, then using StringBuilder
 - no synchronization is performed.
 - StringBuilder lacks some methods split,search
0 голосов
/ 22 февраля 2011

Второй метод имеет определенное преимущество перед первым, поскольку в случае первого мы создаем новый строковый объект с оператором new, который является неизменным, но в случае String Builder, как следует из названия, мы добавляем исходную строку, тем самыммы не создаем дополнительные новые объекты String, тем самым сохраняя память в случае String Buiilder. String Builder, такой как String Buffer, также является изменяемым.

...