Предисловие
Среди разработчиков Java высокая занятость ресурсов струн часто является горячей темой.
Давайте подробно обсудим, почему он занимает высокие ресурсы.
В Java струнный объект неизменен, что означает, что после его создания вы больше не можете его изменить. Поэтому, когда мы разбивают струны, мы создаем новую строку, а старая отмечена коллекционером мусора.
Если мы обрабатываем миллионы строк, то мы генерируем миллионы дополнительных строк, которые будут обработаны сборщиком мусора.
В большинстве учебных пособий вы можете увидеть, что использование + вывески для строк сплайсинга будет генерировать несколько строк, что приведет к плохой производительности. Рекомендуется использовать STRINGBUFFER/StringBuilder для сплайса.
Но это действительно так?
Эта статья провела следующий эксперимент в JDK8:
public static void main (string [] args) {string result = ""; Результат += "еще несколько данных"; System.out.println (результат); }Разключение через javap -c, чтобы получить:
Код: 0: ALOAD_0 // Нажмите «This» в стек 1: invokespecial #1 // inloke Constructor Class // pop 'this' ref из стека 4: return // return из конструктора Public static void main (java.lang.string []); Код: 0: LDC #2 // Загрузите константу #2 на стек 2: store_1 // Создать локальный вар из стека (POP #2) 3: Новый #3 // POLL NEW StringBuilder REF ON Stack 6: DUP // Duplicate В верхней части стека 7: ALADEPECIAL #4 // vlingBuilder Constructor // POP -объект. #5 // invoke method stringbuilder.append () // pop obj ссылка + параметр // push -результат (Stringbuilder ref) 14: LDC #6 // Нажмите «немного данных». 22: store_1 // Создать локальный var из стека (POP #6) 23: GetStatic #8 // System. System.out: PrintStream 26: Aload_1 // push local переменная, содержащая #6 27: Invokevirtual #9 // invoke method printstream.println () // pop дважды (параметр объекта.
Вы можете видеть, что компилятор Java оптимизирует сгенерированный байт -код, автоматически создает StringBuilder и выполняет операции приложения.
Поскольку подстроки окончательной строки уже известны во время компиляции, компилятор Java выполнит вышеуказанную оптимизацию в этом случае. Эта оптимизация называется статической оптимизацией конкатенации строки и была включена со времен JDK5.
Означает ли это, что после JDK5 нам больше не нужно вручную генерировать StringBuilder, и мы можем достичь одной и той же производительности через знак +?
Давайте попробуем динамически сплайсинг струны:
Динамические строки сплайсинга относятся к подстрокам, которые известны только во время выполнения. Например, добавление строки в петлю:
public static void main (string [] args) {string result = ""; for (int i = 0; i <10; i ++) {result+= "больше данных"; } System.out.println (result); }Также декомпилировано:
Код: 0: ALOAD_0 // Нажмите «This» в стек 1: invokespecial #1 // inloke Constructor Class // pop 'this' ref из стека 4: return // return из конструктора Public static void main (java.lang.string []); Код: 0: LDC #2 // Загрузите постоянную #2 на стек 2: store_1 // Создать локальный вар // Push constant 10e6 on to the stack 10: dcmpg // Compare two doubles on top of stack // pop twice, push result: -1, 0 or 1 11: ifge 40 // if value on top of stack is greater // than or equal to 0 (pop once) // branch to instruction at code 40 14: new #5 // Push new StringBuilder ref on stack 17: dup // Duplicate value on top of the stack 18: invokespecial #6 // invoke StringBuilder Constructor // Справочник по объекту POP 21: ALOAD_1 // Протолкнуть локальный var 1 (пустая строка) // в стек. + param, Result Result 30: InvokeVirtual #9 // invoke stringBuilder.toString // Справочник по объекту POP 33: Store_1 // Создать локальный VAR из стека (POP) 34: IINC 2, 1 // Incrent Local Variable 2 на 1 37: GOTO 5 // Переход к инструкции в код 5 40: GetStatic #10 // Push Pus 44: Invokevirtual #11 // invoke Метод PrintStream.println () // POP дважды (объект ref + parameter) 47: return // return void из метода
Вы можете видеть, что StringBuilder был новым в 14 лет, но в 37, Goto 5. Во время цикла оптимизация не была достигнута, и новые строители StringBuilders постоянно генерировались.
Итак, приведенный выше код похож:
String result = ""; for (int i = 0; i <10; i ++) {stringBuilder tmp = new StringBuilder (); tmp.append (результат); TMP.Append («еще несколько данных»); result = tmp.toString ();} system.out.println (result);Вы можете видеть, что новые строители StringBuilders постоянно генерируются, и благодаря тому, что на исходном StringBuilder больше не будет упоминаться, как мусор, а также увеличивает стоимость GC.
Следовательно, в реальном использовании, когда вы не можете различить, является ли строка статической или динамичной, используйте StringBuilder.
Ссылка:
http://www.pellegrino.link/2015/08/22/string-concatenation-with-java-8.html
Суммировать
Вышеуказанное - все содержание этой статьи. Я надеюсь, что содержание этой статьи имеет определенную справочную ценность для каждого обучения или работы. Если у вас есть какие -либо вопросы, вы можете оставить сообщение для общения. Спасибо за поддержку Wulin.com.