Есть ли «самый быстрый способ» для создания строк в Java? - PullRequest
16 голосов
/ 03 декабря 2009

Обычно я создаю строку в Java следующим образом:

String foo = "123456";

Тем не менее, мой лектор настоял на том, чтобы формировать строку, используя метод format, вот так:

String foo = String.format("%s", 123456);

намного быстрее.

Также он говорит, что использовать класс StringBuilder еще быстрее.

StringBuilder sb = new StringBuilder();
String foo = sb.append(String.format("%s", 123456)).toString();



Какой самый быстрый способ создания строки, , если хотя бы один ?

Они не могут быть на 100% точными, поскольку я мог бы не помнить их полностью.

Ответы [ 9 ]

25 голосов
/ 03 декабря 2009

Если есть только одна строка, то:

String foo = "123456";

Самый быстрый. Вы заметите, что в строке String.format объявлено "%s%", поэтому я не понимаю, как лектор мог подумать, что это быстрее. Плюс к этому у вас есть вызов метода.

Однако, если вы строите строку с течением времени, например, в цикле for, вам нужно использовать StringBuilder. Если вы просто используете +=, то вы создаете новую строку каждый раз, когда вызывается строка +=. StringBuilder намного быстрее, так как он содержит буфер и добавляется к нему каждый раз, когда вы вызываете append.

14 голосов
/ 09 декабря 2009

Немного не по теме, но я бы хотел, чтобы весь миф "не надо использовать плюс конкатенация строк в Java" исчезнет. Хотя в ранних версиях Java могло быть верно, что StringBuffer был быстрее и «+ был злым», это, безусловно, неверно в современных JVM, которые заботятся о многих оптимизациях.

Например, что быстрее?

String s = "abc" + "def";

или

    StringBuffer buf = new StringBuffer();
    buf.append("abc");
    buf.append("def");
    String s = buf.toString();

Ответ первый. JVM распознает, что это строковая константа, и фактически помещает «abcdef» в пул строк, тогда как версия «оптимизированного строкового буфера» приведет к созданию дополнительного объекта StringBuffer.

Другая оптимизация JVM -

String s = onestring + " concat " + anotherstring;

Где будет работать JVM, каким будет лучший способ объединения. В JDK 5 это означает, что StringBuilder будет использоваться внутри и будет быстрее, чем использование строкового буфера.

Но, как уже говорили другие ответы, константа "123456" в вашем вопросе, безусловно, самый быстрый путь, и ваш лектор должен вернуться к тому, чтобы стать студентом: -)

И да, мне было грустно проверить это, посмотрев на байт-код Java ...

11 голосов
/ 03 декабря 2009

Вся эта дискуссия спорна. Пожалуйста, прочитайте эту статью Джеффа, то есть парня, который создал переполнение стека.

Печальная трагедия театра микрооптимизации

Пожалуйста, отошлите вашего инструктора к этому посту и попросите его прекратить разрушать мозги своего ученика бесполезной информацией. Алгоритмическая оптимизация - это то, где ваш код будет жить или умирать, а не то, какой метод вы используете для построения строк. В любом случае, StringBuilder и String formatter должны выполнить ACTUAL CODE с REAL MEMORY, если вы просто создаете строку, она откладывается во время компиляции и готова к использованию, когда вам это нужно, по сути, она имеет 0 затраты времени, в то время как другие варианты имеют реальную стоимость, поскольку код фактически должен быть выполнен.

8 голосов
/ 03 декабря 2009
String foo = "some string literal";

Это, безусловно, самый быстрый способ сделать строку. Он встроен в файл .class и представляет собой простой поиск в памяти для извлечения.

Использование String.format, когда вам нечего реально отформатировать, выглядит просто некрасиво и может заставить начинающих разработчиков плакать.

Если строка будет изменена, то StringBuilder является лучшим, поскольку Strings являются неизменными .

5 голосов
/ 03 декабря 2009

Во втором примере, используя:

String foo = String.format("%s", 123456);

ничего не покупает; 123456 уже является постоянным значением, так почему бы просто не присвоить foo = "123456"? Для константных строк лучшего способа нет.

Если вы создаете строку из нескольких частей, добавляемых вместе во время выполнения, используйте StringBuffer или StringBuilder (первая из них является потоко-безопасной)

4 голосов
/ 03 декабря 2009

Если ваша строка известна во время компиляции, тогда лучше использовать литерал: String foo = "123456";.

Если ваша строка неизвестна во время компиляции и состоит из агрегации более мелких строк, StringBuilder - это обычно путь (но будьте осторожны с безопасностью потоков!).

Использование String foo = String.format("%s", 123456); может уменьшить размер вашего .class и сделать загрузку классов немного быстрее, но это будет чрезвычайно агрессивно (экстремально) настраивать память там ^^.

3 голосов
/ 03 декабря 2009

Как уже указывалось, если вы просто строите одну строку без конкатенации, просто используйте String.

Для объединения нескольких битов в одну большую строку StringBuffer работает медленнее, чем StringBuilder, но StringBuffer синхронизируется. Если вам не нужна синхронизация, StringBuilder.

2 голосов
/ 04 декабря 2009

Вы на 100% уверены, что инструктор не говорил о чем-то вроде:

String foo = "" + 123456;

Я вижу, что мои студенты делают такие вещи "все время" (горстка будет делать это каждый семестр). Причина, по которой они это делают, заключается в том, что некоторые книги показали им, как это сделать таким образом. Трясет головой и кулаком ленивым книжникам!

1 голос
/ 04 декабря 2009

Первый приведенный вами пример самый быстрый и простой. Используйте это.

Каждый фрагмент кода, добавленный вами в этих примерах, делает его значительно медленнее и труднее для чтения.

Я бы предложил пример 2 по крайней мере в 10-100 раз медленнее, чем пример 1, а пример 3 примерно в 2 раза медленнее, чем пример 2.

Ваш процессор предоставил какое-либо обоснование для этого утверждения?

Кстати: ваш первый пример вообще не создает String (поэтому он самый быстрый), он просто передает вам String, сидящую в пуле констант String.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...