Мне интересно, может ли кто-нибудь дать мне ответ, какой из этих операторов будет лучше работать в java с использованием объекта StringBuilder:
С использованием
.append(string1 + string 2)
vs
.append(string1).append(string2)
Мне интересно, может ли кто-нибудь дать мне ответ, какой из этих операторов будет лучше работать в java с использованием объекта StringBuilder:
С использованием
.append(string1 + string 2)
vs
.append(string1).append(string2)
Второй вариант почти наверняка будет лучше (при условии, что существует какая-либо заметная разница в производительности). Когда вы пишете что-то вроде
string1 + string2
это внутренне переведено на
new StringBuilder(string1).append(string2).toString()
т.е. создается new StringBuilder для объединения строк. Ваш второй вариант позволяет обойти эту проблему, поскольку он присоединяется непосредственно к существующему StringBuilder, избегая создания нового.
Мы можем взглянуть на байт-код для каждой опции:
public class Concat {
private static String s1 = "foo";
private static String s2 = "bar";
public static String good() {
StringBuilder b = new StringBuilder();
b.append(s1).append(s2);
return b.toString();
}
public static String bad() {
StringBuilder b = new StringBuilder();
b.append(s1 + s2);
return b.toString();
}
}
$javap -c Concat.class
public static java.lang.String good();
Code:
0: new #2 // class java/lang/StringBuilder
3: dup
4: invokespecial #3 // Method java/lang/StringBuilder."<init>":()V
7: astore_0
8: aload_0
9: getstatic #4 // Field s1:Ljava/lang/String;
12: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: getstatic #6 // Field s2:Ljava/lang/String;
18: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: pop
22: aload_0
23: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
26: areturn
public static java.lang.String bad();
Code:
0: new #2 // class java/lang/StringBuilder
3: dup
4: invokespecial #3 // Method java/lang/StringBuilder."<init>":()V
7: astore_0
8: aload_0
9: new #2 // class java/lang/StringBuilder
12: dup
13: invokespecial #3 // Method java/lang/StringBuilder."<init>":()V
16: getstatic #4 // Field s1:Ljava/lang/String;
19: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
22: getstatic #6 // Field s2:Ljava/lang/String;
25: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
28: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
31: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
34: pop
35: aload_0
36: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
39: areturn
Ваш первый вариант фактически становится append(new StringBuilder().append(s1).append(s2).toString()).
Первый текст быстрее набирается и во многих ситуациях легче читать.
Второй может работать немного лучше (согласно байт-коду Джеффри и объяснению Аршаджи).
Однако такая конкатенация строк вряд ли станет узким местом в вашей системе! Если производительность является проблемой, вам нужно профилировать. Компиляторы различаются. И улучшение алгоритмов обычно оказывает гораздо большее влияние, чем такая микрооптимизация.
Не выполняйте оптимизацию раньше, чем это необходимо! Действительно! Это так заманчиво и такая трата времени.
Можно разумно ожидать, что будущее улучшение компилятора заставит обе альтернативы генерировать один и тот же код.
+; компилятор объединится во время компиляции. В противном случае используйте два добавления. - person Ed Staub   schedule 19.12.2013