2013-02-08 3 views
8

Вариант 1:Конкат целое число со строкой - используйте строковый литерал или примитив с точки зрения производительности и памяти?

String newStr = someStr + 3 + "]"; 

Вариант 2:

String newStr = someStr + "3" + "]"; 

Какой вариант лучше в отношении производительности, памяти и общей практики? Какие рекомендуемые инструменты/способы я могу использовать для измерения использования памяти моего кода и его производительности (помимо измерения времени начала и времени окончания и вычисления разницы)

+0

Оба не имеют никакого значения. – Smit

+0

@Smit: компилятор будет использовать 'StringBuilder' для конкатенации строк. – jlordo

+0

@Smit: использование StringBuilder приведет к тому же байт-коду, что и код в вопросе, или, что еще хуже. –

ответ

6

Не будет заметной разницы между обоими , Используйте то, что вы найдете наиболее логичным и читаемым. Я хотел бы использовать

String newStr = someStr + "3]"; 
3

Я бы рекомендовал Jprofiler как большой профилирующий инструмент Java-приложения, которые помогли мне найти много проблем с памятью.

Я не думаю, что варианты 1 и 2 имеют большую разницу в использовании памяти, особенно если это относится к настольному приложению.

+0

Спасибо за подсказку! – user1739658

+0

Нет проблем! Примите самый полезный ответ ;-) – Simon

10

Первое будут:

StringBuilder sb = new StringBuilder (String.valueOf (someStr)); 
sb.append (3); 
sb.append ("]"); 
String newStr = sb.toString(); 

второй станет:

StringBuilder sb = new StringBuilder (String.valueOf (someStr)); 
sb.append ("3"); 
sb.append ("]"); 
String newStr = sb.toString(); 

Вот разборка:

public String foo (String someStr) 
{ 
    String newStr = someStr + 3 + "]"; 
    return newStr; 
} 

public String bar (String someStr) 
{ 
    String newStr = someStr + "3" + "]"; 
    return newStr; 
} 

public java.lang.String foo(java.lang.String); 
Code: 
    0: new   #16     // class java/lang/StringBuilder 
    3: dup 
    4: aload_1 
    5: invokestatic #18     // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 
    8: invokespecial #24     // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 
    11: iconst_3 
    12: invokevirtual #27     // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 
    15: ldc   #31     // String ] 
    17: invokevirtual #33     // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    20: invokevirtual #36     // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
    23: astore_2 
    24: aload_2 
    25: areturn 

public java.lang.String bar(java.lang.String); 
Code: 
    0: new   #16     // class java/lang/StringBuilder 
    3: dup 
    4: aload_1 
    5: invokestatic #18     // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 
    8: invokespecial #24     // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 
    11: ldc   #44     // String 3 
    13: invokevirtual #33     // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    16: ldc   #31     // String ] 
    18: invokevirtual #33     // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    21: invokevirtual #36     // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
    24: astore_2 
    25: aload_2 
    26: areturn 
+3

Первый добавит '3' (вставляется в Integer 3), а затем добавит'] '. Второй добавляет '3 '' –

+0

+1. Я не знаю, почему, но мои глаза видели постоянную во втором случае, но не в первом. –

+0

К сожалению. Стив Куо прав.'String s =" hello "+ 3 +"] "' создает одиночный String '" hello3 "". Странно, что компилятор не может оптимизировать этот случай. +1 все еще, потому что я чему-то научился. –

1

Предполагая, что SomeString постоянен, оба константных выражений и будет оцениваться во время компиляции. Они приведут к идентичным файлам классов и времени выполнения.

Источник: Java Language Specification пишет: константа

времени компиляции является выражение, обозначающее значение примитивного типа или строка, которая не завершается внезапно и состоит, используя только следующее:

  • литералы примитивного типа и литералы типа String (§3.10.1, §3.10.2, §3.10.3, §3.10.4, §3.10.5)

  • добавка õpe rators + и - (§15.18)

  • ...

Compile времени константные выражения типа String, всегда "интернированы" с тем, чтобы разделить уникальные экземпляры, используя метод String.intern.

Если SomeString не является постоянным, большинство современных компиляторов будут использовать StringBuilder, который явно permitted по спецификации языка Java:

Результат конкатенации является ссылкой на объект Струнный что является конкатенацией двух операндов. Символы левого операнда предшествуют символам правого операнда во вновь созданной строке.

Объект String только что создан (§12.5), если выражение не является постоянным выражением времени компиляции (§15.28).

Реализация может выбрать выполнение преобразования и конкатенации за один шаг, чтобы избежать создания и последующего удаления промежуточного объекта String. Чтобы увеличить производительность повторной конкатенации строк, компилятор Java может использовать класс StringBuffer или подобный метод для уменьшения количества промежуточных объектов String, созданных при оценке выражения.

Для примитивных типов реализация может также оптимизировать создание объекта-обертки путем преобразования непосредственно из примитивного типа в строку.

+0

Это очень полезно. Большое спасибо! – user1739658

0

Всякий раз, когда вы объединяете строку, на каждой конкатенации вы создаете новую копию строки, и обе строки копируются за один символ за раз. Это приводит к временной сложности O (n) (McDowell).

Если вы хотите улучшить производительность, используйте

StringBuilder 

Один из конструкторов имеет следующий синтаксис: (. Изменяемую последовательность символов Помните строки immmutable)

public StringBuilder(int size); //Contains no character. Initial capacity of 'size'. 

StringBuilder помогает решить эту проблему проблему, просто создав изменяемый массив из всех строк. копируя их обратно в строку только при необходимости (McDowell).

StringBuilder str = new StringBuilder(0); 
str.append(someStr); 
str.append(3); 
str.append("]"); 

Ссылка:

Макдауэлл, Гейл Laakmann. Cracking The Coding Interview, 6-е издание. Распечатать.

"Stringbuilder (платформа Java SE 8)". Docs.oracle.com. N.p., 2016. Web. 4 июня 2016.