Есть ли ощутимая разница между использованием String.format
и объединением строк в Java?
Я склонен использовать, String.format
но иногда проскальзываю и использую сцепление. Мне было интересно, если один был лучше, чем другой.
То, как я это вижу, String.format
дает вам больше возможностей для «форматирования» строки; и конкатенация означает, что вам не нужно беспокоиться о случайном добавлении% s или об отсутствии.
String.format
тоже короче.
Какой из них более читабелен, зависит от того, как работает ваша голова.
java
string
concatenation
string.format
Омар Кохеджи
источник
источник
Ответы:
Я бы предположил, что это лучше использовать
String.format()
. Основная причина в том, чтоString.format()
его легче локализовать с помощью текста, загруженного из файлов ресурсов, тогда как конкатенация не может быть локализована без создания нового исполняемого файла с различным кодом для каждого языка.Если вы планируете, чтобы ваше приложение было локализуемым, вы должны также привыкнуть указывать позиции аргументов для ваших токенов формата:
Затем его можно локализовать и поменять местами токены имени и времени, не требуя перекомпиляции исполняемого файла для учета другого порядка. С позициями аргументов вы также можете повторно использовать один и тот же аргумент, не передавая его в функцию дважды:
источник
О производительности:
Результаты синхронизации следующие:
Следовательно, конкатенация выполняется намного быстрее, чем String.format.
источник
javap -c StringTest.class
вы увидите, что компилятор автоматически преобразует «+» в StringBuilder, только если вы не находитесь в цикле. Если конкатенация выполняется в одну строку, это то же самое, что и использование «+», но если вы используетеmyString += "morechars";
илиmyString += anotherString;
несколько строк, вы заметите, что может быть создано более одного StringBuilder, поэтому использование «+» не всегда так эффективно как StringBuilder.+
не конвертируются в,StringBuilder.append()
а вместо этогоnew StringBuilder()
происходит на каждой итерации.Поскольку есть обсуждение производительности, я подумал, что я бы добавил в сравнение, которое включало StringBuilder. Это на самом деле быстрее, чем concat и, естественно, опция String.format.
Чтобы сделать это своего рода сравнением яблок с яблоками, я создаю новый цикл StringBuilder в цикле, а не снаружи (это на самом деле быстрее, чем выполнение только одного экземпляра, скорее всего, из-за накладных расходов на перераспределение пространства для цикла, добавляемого в конце один строитель).
источник
String
. Если честно, тест StringBuilder требует заключительного шага, который превращает содержимое StringBuilder в строку. Вы делаете это по телефонуbldString.toString()
. Я надеюсь, что это объясняет?String s = bldString.toString();
Тайминги были с конкатенацией и StringBuilder почти на одном уровне друг с другом:Format = 1520 millisecond
,Concatenation = 167 millisecond
,String Builder = 173 millisecond
я побежал их в цикле и в среднем каждый, чтобы получить хорошую репутацию: (предварительно Jvm оптимизацию, попробую 10000+ цикла , когда я получаю время)Одна из проблем
.format
заключается в том, что вы теряете безопасность статического типа. У вас может быть слишком мало аргументов для вашего формата, и у вас могут быть неправильные типы для спецификаторов формата - оба приводят к возникновениюIllegalFormatException
во время выполнения , так что вы можете в конечном итоге получить код, который нарушает работу.Напротив, аргументы для
+
могут быть проверены компилятором.История безопасности вPrintf(на котором
format
моделируется функция) долго и пугающе.источник
Вы получили свой ответ прямо там.
Это вопрос личного вкуса.
Полагаю, что сцепление строк незначительно быстрее, но это должно быть незначительным.
источник
Вот тест с несколькими размерами выборки в миллисекундах.
}
источник
Вот тот же тест, что и выше, с модификацией вызова метода toString () в StringBuilder . Результаты ниже показывают, что подход StringBuilder немного медленнее, чем конкатенация строк с использованием оператора + .
файл: StringTest.java
Команды оболочки: (скомпилируйте и запустите StringTest 5 раз)
Полученные результаты :
источник
String.format()
это больше, чем просто объединение строк. Например, вы можете отображать числа в определенной локали, используяString.format()
.Однако, если вас не волнует локализация, функциональной разницы нет. Может быть, один быстрее, чем другой, но в большинстве случаев он будет незначительным ..
источник
Как правило, объединение строк должно быть предпочтительнее, чем
String.format
. Последний имеет два основных недостатка:Под пунктом 1 я имею в виду, что невозможно понять, что
String.format()
делает вызов за один последовательный проход. Один вынужден переходить назад и вперед между строкой формата и аргументами при подсчете позиции аргументов. Для коротких конкатенаций это не большая проблема. Однако в этих случаях конкатенация строк менее многословна.Под пунктом 2 я подразумеваю, что важная часть процесса сборки кодируется в строке формата (с использованием DSL). Использование строк для представления кода имеет много недостатков. Он не является типично безопасным по типу и усложняет подсветку синтаксиса, анализ кода, оптимизацию и т. Д.
Конечно, при использовании инструментов или сред, внешних по отношению к языку Java, в игру могут вступать новые факторы.
источник
Я не делал каких-либо конкретных тестов, но я думаю, что объединение может быть быстрее. String.format () создает новый Formatter, который, в свою очередь, создает новый StringBuilder (размером всего 16 символов). Это значительный объем накладных расходов, особенно если вы форматируете более длинную строку, а StringBuilder продолжает изменять размер.
Однако конкатенация менее полезна и труднее для чтения. Как всегда, стоит сделать тест на вашем коде, чтобы увидеть, что лучше. Различия могут быть незначительными в серверном приложении после загрузки пакетов ресурсов, локалей и т. Д. В память и кода JITted.
Возможно, в качестве лучшей практики было бы неплохо создать собственный форматтер с правильно подобранным StringBuilder (Appendable) и Locale и использовать его, если вам нужно много форматирования.
источник
Там может быть ощутимая разница.
String.format
довольно сложный и использует регулярное выражение внизу, так что не делайте это привычкой использовать его везде, но только там, где вам это нужно.StringBuilder
будет на порядок быстрее (как кто-то здесь уже указал).источник
Я думаю, что мы можем продолжать,
MessageFormat.format
как это должно быть хорошо как с точки зрения читаемости, так и с точки зрения производительности.Я использовал ту же программу, которую использовал Icaro в своем ответе выше, и добавил в нее дополнительный код для
MessageFormat
объяснения показателей производительности.ОБНОВЛЕНИЕ:
Согласно отчету SonarLint, строки формата в стиле Printf должны использоваться правильно (squid: S3457)
Поскольку
printf-style
строки формата интерпретируются во время выполнения, а не проверяются компилятором, они могут содержать ошибки, которые приводят к созданию неправильных строк. Это правило статический проверяет корреляциюprintf-style
строк формата для их аргументов при вызове методов формата (...) изjava.util.Formatter
,java.lang.String
,java.io.PrintStream
,MessageFormat
, иjava.io.PrintWriter
классов иprintf(...)
методаjava.io.PrintStream
илиjava.io.PrintWriter
классы.Я заменил стиль printf на фигурные скобки и получил кое-что интересное, как показано ниже.
Мой вывод:
как я уже отмечал выше, использование String.format с фигурными скобками должно быть хорошим выбором для получения преимуществ хорошей читаемости, а также производительности.
источник
Вы не можете сравнивать String Concatenation и String.Format с помощью указанной выше программы.
Вы можете попробовать это также поменять местами использование ваших String.Format и Concatenation в вашем блоке кода, как показано ниже
Вы будете удивлены, увидев, что Формат работает здесь быстрее. Это связано с тем, что созданные объекты могут быть не выпущены, и может возникнуть проблема с выделением памяти и, следовательно, с производительностью.
источник
Требуется немного времени, чтобы привыкнуть к String.Format, но в большинстве случаев оно того стоит. В мире NRA (никогда ничего не повторяйте) чрезвычайно полезно хранить ваши токенизированные сообщения (ведение журнала или пользователя) в библиотеке констант (я предпочитаю то, что равно статическому классу) и вызывать их по мере необходимости с помощью String.Format независимо от того, используете ли вы локализуются или нет. Попытки использовать такую библиотеку с методом конкатенации труднее читать, устранять неполадки, корректировать и управлять любым подходом, требующим конкатенации. Замена - это вариант, но я сомневаюсь, что он эффективен. После многих лет использования моя самая большая проблема с String.Format заключается в том, что длина вызова неудобно велика, когда я передаю его в другую функцию (например, Msg), но это легко обойти с помощью пользовательской функции, служащей псевдонимом. ,
источник