Есть ли "самый быстрый способ" для создания строк в Java?
Я обычно создаю String в 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% точными, поскольку я не мог их полностью запомнить.
Ответы
Ответ 1
Если есть только одна строка, то:
String foo = "123456";
Самый быстрый. Вы заметите, что строка String.format
имеет "%s%"
, объявленную в ней, поэтому я не вижу, как лектор мог подумать, что это было быстрее. Кроме того, у вас есть вызов метода поверх него.
Однако, если вы создаете строку с течением времени, например, в цикле for, вы захотите использовать StringBuilder. Если бы вы просто использовали +=
, тогда вы создаете новую строку каждый раз, когда вызывается строка +=
. StringBuilder намного быстрее, так как он содержит буфер и присоединяется к нему каждый раз, когда вы вызываете append
.
Ответ 2
Немного не по теме, но я хочу, чтобы весь миф "must-not-use-plus-to-concatenate-strings-in-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...
Ответ 3
Вся эта дискуссия спорная. Пожалуйста, прочитайте эту статью Джеффом, то есть парнем, создавшим переполнение стека.
Печальная трагедия в тесте микро-оптимизации
Пожалуйста, обратитесь к своему преподавателю на этот пост и попросите его прекратить разрушать его/ее мозг с бесполезной информацией. Алгоритмическая оптимизация - это то, где ваш код будет жить или умереть, а не каким методом вы используете для построения строк. В любом случае StringBuilder и String formatter должны выполнять ACTUAL CODE с REAL MEMORY, если вы просто создаете строку, которую она отбрасывает во время компиляции и готова к использованию, когда вам это нужно, по сути, она имеет 0 run- а другие варианты имеют реальную стоимость, поскольку код действительно должен быть выполнен.
Ответ 4
String foo = "some string literal";
Является, безусловно, самым быстрым способом создания String. Он встроен в файл .class и представляет собой простой способ поиска в памяти.
Использование String.format
, когда вам нечего форматировать, просто выглядит уродливым и может заставить программистов-младших плакать.
Если строка будет изменена, то StringBuilder
является лучшим, поскольку Strings
immutable.
Ответ 5
Если ваша строка известна во время компиляции, лучше использовать литерал String foo = "123456";
.
Если ваша строка неизвестна во время компиляции и состоит из агрегации меньших строк, StringBuilder
обычно является способом выхода (но остерегайтесь безопасности потоков!).
Использование String foo = String.format("%s", 123456);
может уменьшить размер вашего .class и сделать его загрузку по-чуть-чуть быстрее, но это будет чрезвычайно агрессивная (экстремальная) настройка памяти там ^^.
Ответ 6
В вашем втором примере, используя:
String foo = String.format("%s", 123456);
ничего не покупает; 123456 уже является постоянным значением, так почему бы просто не назначить foo = "123456"? Для постоянных строк нет лучшего способа.
Если вы создаете строку из нескольких частей, добавляемых вместе во время выполнения, используйте StringBuffer или StringBuilder (первый из которых является потокобезопасным).
Ответ 7
Как уже указывалось, если вы просто строите одну строку без конкатенации, просто используйте String.
Для объединения нескольких бит в одну большую строку StringBuffer работает медленнее, чем StringBuilder, но StringBuffer синхронизируется. Если вам не нужна синхронизация, StringBuilder.
Ответ 8
Вы на 100% уверены, что инструктор не говорил о чем-то вроде:
String foo = "" + 123456;
Я вижу, что мои ученики делают это "все время" (горстка сделает это каждый термин). Причина, по которой они делают это, заключается в том, что в какой-то книге они показали, как это делается. Качает головой и кулаком по ленивым книгам!
Ответ 9
Первый пример, который вы дали, является самым быстрым и простым. Используйте это.
Каждый фрагмент кода, который вы добавили в этих примерах, делает его значительно медленнее и труднее читать.
Я бы предположил, что пример 2 по меньшей мере на 10-100x медленнее, чем пример 1, а пример 3 примерно в 2 раза медленнее, чем пример 2.
Был ли ваш процессор оправданным для этого утверждения?
BTW: ваш первый пример вообще не строит строку (именно поэтому она самая быстрая), она просто передает вам строку, расположенную в пуле констант String.