public class One {
public static void main(String[] args) {
String string = new String("My string test");
string += " for String class";
}
}
public class Two {
public static void main(String[] args) {
StringBuffer string = new StringBuffer("My string test");
string.append(" for String class");
}
}
public class StrBuild {
public static void main(String[] args) {
StringBuilder string = new StringBuilder("My string test");
string.append(" for String class");
}
}
1 Сравнение байт-кода
Сравниваем байт-код с помощью
javap -c NameOfClass.classВ результате получаем следующий вывод на экран:
Compiled from "One.java"
public class Strings.One {
public Strings.One();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #16 // class java/lang/String
3: dup
4: ldc #18 // String My string test
6: invokespecial #20 // Method java/lang/String."":(Ljava/lang/String;)V
9: astore_1
10: new #23 // class java/lang/StringBuilder
13: dup
14: aload_1
15: invokestatic #25 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
18: invokespecial #29 // Method java/lang/StringBuilder."":(Ljava/lang/String;)V
21: ldc #30 // String for String class
23: invokevirtual #32 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
26: invokevirtual #36 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
29: astore_1
30: return
}
Compiled from "Two.java"
public class Strings.Two {
public Strings.Two();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #16 // class java/lang/StringBuffer
3: dup
4: ldc #18 // String My string test
6: invokespecial #20 // Method java/lang/StringBuffer."":(Ljava/lang/String;)V
9: astore_1
10: aload_1
11: ldc #23 // String for String class
13: invokevirtual #25 // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
16: pop
17: return
}
Compiled from "StrBuild.java"
public class Strings.StrBuild {
public Strings.StrBuild();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #16 // class java/lang/StringBuilder
3: dup
4: ldc #18 // String My string test
6: invokespecial #20 // Method java/lang/StringBuilder."":(Ljava/lang/String;)V
9: astore_1
10: aload_1
11: ldc #23 // String for String class
13: invokevirtual #25 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
16: pop
17: return
}
Здесь видно, что байт-код StringBuffer и StringBuilder оказался почти в два раза короче, чем для String. 2 Время выполнения
Для оценки быстродействия двух классов был использован следующий алгоритм:
public class Three {
public static String concatWithString() {
String t = "Cat";
for (int i = 0; i < 100000; i++) {
t += "Dog";
}
return t;
}
public static String concatWithStringBuffer() {
StringBuffer sb = new StringBuffer("Cat");
for (int i = 0; i < 100000; i++) {
sb.append("Dog");
}
return sb.toString();
}
public static String concatWithStringBuilder() {
StringBuilder sb = new StringBuilder("Cat");
for (int i = 0; i < 100000; i++) {
sb.append("Dog");
}
return sb.toString();
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
concatWithString();
System.out.println("Concat with String took: " + (System.currentTimeMillis() - start) + "ms");
start = System.currentTimeMillis();
concatWithStringBuffer();
System.out.println("Concat with StringBuffer took: " + (System.currentTimeMillis() - start) + "ms");
start = System.currentTimeMillis();
concatWithStringBuilder();
System.out.println("Concat with StringBuilder took: " + (System.currentTimeMillis() - start) + "ms");
}
}
В результате я получил следующие значения:
Concat with String took: 12478ms Concat with StringBuffer took: 6ms Concat with StringBuilder took: 4msИспользуя полученные результаты и документацию можно сделать следующие выводы
1) String является неизменяемым объектом (immutable), в то время как StringBuffer и StringBuilder являются изменяемыми объектами (mutable).
2) Используйте String вам требуется неизменяемый объект, Stringbuffer - если требуется изменяемый и потокобезопасность, StringBuilder изменяемый и не требуется обеспечивать безопасность потоков.
Комментариев нет:
Отправить комментарий