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."Здесь видно, что байт-код StringBuffer и StringBuilder оказался почти в два раза короче, чем для String.":()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 }
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 изменяемый и не требуется обеспечивать безопасность потоков.
Комментариев нет:
Отправить комментарий