Я был занят логической реализацией проекта в будние дни. У меня было некоторое время в субботу, поэтому я вытащил толстую английскую версию «Мышления» в Java из книжного шкафа и прочитал сплайсинг струнных объектов. Обратитесь к этой книге как перевод, добавьте то, о чем вы думаете, и напишите эту статью, чтобы записать ее.
Необычный строковый объект
В Java объекты строки неизменны (неизменные). В коде вы можете создать несколько псевдонима для строкового объекта. Но ссылки этих псевдонимов одинаковы.
Например, S1 и S2 являются псевдонимом для объектов "droidyue.com", а псевдоним хранятся в ссылках на реальный объект. Итак, S1 = S2
String s1 = "droidyue.com"; string s2 = s1; system.out.println ("s1 и s2 имеет одинаковую ссылку =" + (s1 == s2));Единственный перегруженный оператор в Java
В Java единственный перегруженный оператор связан с сплайсингом строк. +,+=. Кроме того, дизайнеры Java не позволяют перегружать других операторов.
Анализ сплайсинга
Есть ли действительно стоимость производительности?
После понимания двух вышеупомянутых пунктов у вас могут быть такие мысли. Поскольку объект STING неизменен, сплайсинг множественных (трех или более) строк неизбежно будет производить ненужные объекты промежуточных строк.
String username = "andy"; string age = "24"; string job = "Разработчик"; строка info = имя пользователя + возраст + job;
Чтобы получить вышеуказанную информацию, имени пользователя и возраста будут сплачиваны для создания временного строкового объекта T1, с содержанием Andy24, а затем T1 и задания будут сплачиваны, чтобы генерировать информационный объект, который нам нужен в конце. Среди них генерируется промежуточный T1, и после создания T1 он не будет переработан автоматически, что неизбежно будет занимать определенное количество места. Если это сплайсинг много (при условии, что сотни, более распространенные в строке ToString к объекту), то стоимость будет больше, а производительность будет намного ниже.
Обработка оптимизации компилятора
Есть ли на самом деле вышеуказанная стоимость производительности? Спилочный сплайсинг в строке так распространен, нет ли специальной оптимизации обработки? Ответ заключается в том, что эта оптимизация выполняется, когда компилятор компилируется. Ява к байткоду.
Если программа Java хочет запустить, потребуется два периода, время компиляции и время выполнения. Во время компиляции компилятор Java (компилятор) преобразует файл Java в ByteCode. Во время выполнения виртуальная машина Java (JVM) запускает сгенерированный временем компиляции. Через эти два периода Java достигла так называемой компиляции и работает повсюду.
Давайте экспериментируем с тем, какие оптимизации были сделаны в течение периода компиляции, и мы создаем кусок кода, который может иметь затраты на производительность.
public Class Concatenation {public static void main (string [] args) {string username = "andy"; String Age = "24"; String job = "Разработчик"; String info = имя пользователя + возраст + job; System.out.println (info); }}Компилирование Concatenation.java. Получить concatenation.class
Javac Concatenation.java
Затем мы используем Javap для декомпиляции скомпилированного файла concatenation.class. Javap -c Concatenation. Если команда Javap не найдена, пожалуйста, рассмотрите возможность добавления каталога, в котором Javap расположен в переменной среды или с использованием полного пути Javap.
17: 22: 04 -androidyue ~/workpace_adt/strings/src $ javap -c concatenationcompilled из "concatenation.java" public Class Concatenation {public concatenation (); Код: 0: aload_0 1: infokpescial #1 // Метод Java/Lang/Object. Код: 0: LDC #2 // String Andy 2: Store_1 3: LDC #3 // String 24 5: Store_2 6: LDC #4 // Строка разработчика 8: Store_3 9: новый #5 // класс Java/Lang/StringBuilder 12: Dup 13: Invokespecial #6 // Method Java/Lang/StringBuilder. InvokeVirtual #7 // Метод java/lang/stringbuilder.append: (ljava/lang/string;) ljava/lang/stringbuilder; 20: aload_2 21: Invokevirtual #7 // Метод Java/lang/stringBuilder.append: (ljava/lang/string;) ljava/lang/stringbuilder; 24: aload_3 25: Invokevirtual #7 // Метод java/lang/stringbuilder.append: (ljava/lang/string;) ljava/lang/stringbuilder; 28: InvokeVirtual #8 // Метод java/lang/stringbuilder.tostring :() ljava/lang/string; 31: Магазин 4 33: GetStatic #9 // Полевой java/lang/system.out: ljava/io/printstream; 36: Aload 4 38: Invokevirtual #10 // Метод Java/io/printStream.println: (ljava/lang/string;) v 41: return}Среди них, НРС, магазин и т. Д. Имеются инструкции по байт -коде Java, аналогичные инструкциям сборки. В следующих комментариях используется контент, связанный с Java для объяснения. Мы видим, что на нем много строк -строителей, но мы называем их без отображения в коде Java. Это оптимизация, сделанная компилятором Java. Когда компилятор Java встречает сплайсинг строки, он создаст объект StringBuilder. Сплайсинг, стоящий за ним, на самом деле вызывает метод добавления объекта StringBuilder. Таким образом, не будет никаких проблем, о которых мы беспокоимся.
Оптимизация компилятора только?
Поскольку компилятор помог нам оптимизировать, достаточно ли этого, чтобы полагаться исключительно на оптимизацию компилятора? Конечно, нет.
Давайте посмотрим на кусок кода, который не был оптимизирован для низкой производительности
public void imploiceSestringBuilder (string [] values) {String result = ""; for (int i = 0; i <values.length; i ++) {result += values [i]; } System.out.println (result);}Скомпилируйте Javac и просмотрите с помощью Javap
11: Новый #5 // класс Java/Lang/StringBuilder 14: DUP 15: Invokespecial #6 // Метод Java/Lang/StringBuilder. "<Int>" :() V 18: Aload_2 19: Invokevirtual #7 // Метод 31: магазин_2 32: Iinc 3, 1 35: goto 5: #9 // #9 // поля. java/lang/system.out: ljava/io/printstream; 41: aload_2 42: Invokevirtual #10 // Метод Java/io/printstream.println: (ljava/lang/string;) V 45: return
Среди них 8: if_icmpge 38 и 35: goto 5 образуют цикл. 8: if_icmpge 38 означает, что если целочисленное сравнение стека операнда JVM больше или равно (противоположный результат i <значения. 35: GOTO 5 означает прыгать прямо на строку 5.
Но здесь есть очень важная вещь, что создание объекта StringBuilder происходит между петлями, что означает, что сколько раз петли будут создавать объекты StringBuilder, что, очевидно, не очень хорошо. Голый код низкого уровня.
Оптимизируйте его немного, чтобы мгновенно улучшить качество.
public void explicitUseStringBuilder (string [] values) {stringBuilder result = new StringBuilder (); for (int i = 0; i <values.length; i ++) {result.append (values [i]); }}Соответствующая скомпилированная информация
11: Aload_1 12: ArrayLength 13: if_icmpge 30 16: aload_2 17: aload_1 18: iload_3 19: aaload 20: invokevirtual #7 // Метод java/lang/stringbuilder.append: (ljava/lang/string;) ljava/lang/stringbuilder; 23: Pop 24: iinc 3, 1 27: goto 10 30: return
Как можно увидеть сверху, 13: if_icmpge 30 и 27: goto 10 образуют петлю петли, а 0: новый #5 находится за пределами цикла, поэтому StringBuilder не создается несколько раз.
В целом, мы должны попытаться избежать неявного или явного создания строк -строителей в теле петли. Поэтому те, кто понимает, как составлен код и как он выполняется внутри, имеют относительно высокие уровни кода.
Если в приведенной выше статье есть ошибки, пожалуйста, критикуйте и исправьте их.
Выше приведено, чтобы разобраться с информацией о сплайсингах струн Java, и мы будем продолжать добавлять соответствующую информацию в будущем. Спасибо за поддержку этого сайта!