powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Генерация повторяющихся String-значений: работает ли при этом intern()-буфер ?
9 сообщений из 9, страница 1 из 1
Генерация повторяющихся String-значений: работает ли при этом intern()-буфер ?
    #38254340
ozzmosis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте.
В следующем примере в цикле генерятся одни и те же 10 строк, каждая по 1 млн раз:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
class StrTest2 {
    final static int N = 10000000;
    final static String pref = "1234567890abcdefghijklmnopqrstuvwxyz";
    public static void main(String[] args) {
      String st;
      long t0=System.currentTimeMillis();
      for(int i=0; i<N; i++) {
        st=(pref+(char)('a'+(i%10)));
        // ... 
      }
      long t1=System.currentTimeMillis();
      System.out.println("Done in "+(t1-t0)+" ms");
    }
}

Эта штука отрабатывает за ~7 сек. Для сравнения, то же самое через StringBuilder:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
class StrTest3 {
    final static int N = 10000000;
    final static String pref = "1234567890abcdefghijklmnopqrstuvwxyz ";
    public static void main(String[] args) throws IOException {

      StringBuilder sb = new StringBuilder( );
      sb.append(pref.toCharArray());
      long t0=System.currentTimeMillis();
      for(int i=0; i<N; i++) {
        sb.setCharAt( sb.length()-1, (char)('a'+(i % 10)));
      }
      long t1=System.currentTimeMillis();
      System.out.println("Done in "+(t1-t0)+" ms");
    }
}

- отрабатывает за 188 мс.

Каждая строка в яве есть immutable-объект, но при создании строк, значения которых естьString intern() description literal strings and string-valued constant expressions- дока говорит про буфер, в котором ищутся значения для возврата (вместо создания новой строки с тем же содержимым).

ВОПРОС-1. Можно ли как-то заставить яву использовать этот буфер и в случаях, когда строки генерятся так, как показано выше: st=(pref+(char)('a'+(i%10))) ?

ВОПРОС-2. Профилирование первого примера в NetBeans'e заставляет его работать в ТРИ раза дольше, т.е. 22 сек вместо 7! Как уменьшить влияние профилировщика ?

ВОПРОС-3. Профайлер показывает, что в первом примере создавалось 10'000'025 строк, однако объем выделенных байтов оказался равным 25'260'284. Как такое может быть, если каждая строка у мну являет собой 36 байт ? Если Ява как-то "жмёт" создаваемые строки, то где про это почитать ?

ВОПРОС-4. Профайлер (опять-таки) показывает, что создавалось 10'000'011 объектов класса StringBuilder. Чтение доки показало, что это из-за использования оператора "+". Но у коде видно, что оператор "+" используется ровно 10 млн раз внутри цикла и еще два раза вне цикла (в System.out.println("Done in "+(t1-t0)+" ms")).
Откуда тогда еще 9 StringBuilder'ов ?

ЗЫ. Замена "+" на вызов concat():
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
class StrTest2 {
    final static int N = 10000000;
    final static String pref = "1234567890abcdefghijklmnopqrstuvwxyz";
    public static void main(String[] args) {
      String st;
      long t0=System.currentTimeMillis();
      for(int i=0; i<N; i++) {
          st=pref.concat( Character.toString( (char)('a'+(i%10)) )  ); // 2625 ms
          //st=pref+(char)('a'+(i%10)); // 6922 ms
      }
      long t1=System.currentTimeMillis();
      System.out.println("Done in "+(t1-t0)+" ms");
    }
}

- улучшила время более чем в два раза (2625 vs 6922 ms), но всё равно хотелось бы понять, есть ли возможность задействовать внутренний буфер строк в таких случаях, как показано выше.
...
Рейтинг: 0 / 0
Генерация повторяющихся String-значений: работает ли при этом intern()-буфер ?
    #38254428
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ozzmosis дока говорит про буфер, в котором ищутся значения для возврата (вместо создания новой строки с тем же содержимым).
Нет там никакого "вместо".

ozzmosisВОПРОС-1. Можно ли как-то заставить яву использовать этот буфер и в случаях, когда строки генерятся так, как показано выше: st=(pref+(char)('a'+(i%10))) ?
Проще свой кэш реализовать. Буфер и кэш это разные понятия.
ozzmosisВОПРОС-2. Профилирование первого примера в NetBeans'e заставляет его работать в ТРИ раза дольше, т.е. 22 сек вместо 7! Как уменьшить влияние профилировщика ?
Там есть сэмплирующий профайлер. Его надо в плагинах доставить. Но не думаю что он сильно поможет на микробенчмарках.

ozzmosisВОПРОС-3. Профайлер показывает, что в первом примере создавалось 10'000'025 строк, однако объем выделенных байтов оказался равным 25'260'284. Как такое может быть, если каждая строка у мну являет собой 36 байт ? Если Ява как-то "жмёт" создаваемые строки, то где про это почитать ?
Часть мог удалить GC. Откуда инфа про 36 байт? На самом деле намного больше. Есть, правда, опция для Compressed Strings. Но не думаю что в ней дело.

ozzmosisВОПРОС-4. Профайлер (опять-таки) показывает, что создавалось 10'000'011 объектов класса StringBuilder. Чтение доки показало, что это из-за использования оператора "+". Но у коде видно, что оператор "+" используется ровно 10 млн раз внутри цикла и еще два раза вне цикла (в System.out.println("Done in "+(t1-t0)+" ms")).
Откуда тогда еще 9 StringBuilder'ов ?

Какая разница? Уменьши количество итераций, поставь брейкпоинт в StringBuilder и смотри откуда конструкторы вызываются.


ozzmosisулучшила время более чем в два раза (2625 vs 6922 ms), но всё равно хотелось бы понять, есть ли возможность задействовать внутренний буфер строк в таких случаях, как показано выше.
Переключения между server/client JVM, а так же предварительный разогрев для JIT компиляции могут показать ещё более удивительные результаты.
...
Рейтинг: 0 / 0
Генерация повторяющихся String-значений: работает ли при этом intern()-буфер ?
    #38254452
ozzmosis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczНет там никакого "вместо".ну, нет так нет; просто померещилось при чтении:String intern()When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned.

BlazkowiczЧасть мог удалить GC. Откуда инфа про 36 байт? На самом деле намного больше. Есть, правда, опция для Compressed Strings. Но не думаю что в ней дело.вот эта хрень: "1234567890abcdefghijklmnopqrstuvwxyz" - имеет длину = 36 байт. КМК.
...
Рейтинг: 0 / 0
Генерация повторяющихся String-значений: работает ли при этом intern()-буфер ?
    #38254457
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ozzmosisКМК.
Домыслы - источник заблуждений.
Во-первых строки - Unicode, а не ASCII.
Во-вторых заходим в класс String видим какие-то поля помимо char[] (зависит от версии Java)
В-третих Java объект сам по себе имет некий заголовок ненулевого размера.
...
Рейтинг: 0 / 0
Генерация повторяющихся String-значений: работает ли при этом intern()-буфер ?
    #38273223
ozzmosis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Подниму-ка тему.

Допустим, прога читает строки из текстового файла (скажем, "Войну и Мир"). И каждую такую строку присваивает одной и той же String-переменной `s`.
Вопрос: будет ли в итоге string pool (в предположении, что он достаточного размера) содержать уникальный список прочитанных строк ?
То есть, если далее я попробую создать новую переменную String s2 = "Пьер Безухов" - будет в строковом буфере эта строка ?
...
Рейтинг: 0 / 0
Генерация повторяющихся String-значений: работает ли при этом intern()-буфер ?
    #38273241
Фотография schwa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ozzmosisПодниму-ка тему.

Допустим, прога читает строки из текстового файла (скажем, "Войну и Мир"). И каждую такую строку присваивает одной и той же String-переменной `s`.
Вопрос: будет ли в итоге string pool (в предположении, что он достаточного размера) содержать уникальный список прочитанных строк ??
Там не будет ничего. Ибо все строки будут создаваться через new String(...).
...
Рейтинг: 0 / 0
Генерация повторяющихся String-значений: работает ли при этом intern()-буфер ?
    #38273248
ozzmosis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
schwaТам не будет ничего. Ибо все строки будут создаваться через new String(...).это если к ним далее не применять intern()
...
Рейтинг: 0 / 0
Генерация повторяющихся String-значений: работает ли при этом intern()-буфер ?
    #38273256
ozzmosis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
PS. Вроде как нашел ответ в ководстве по сдаче SCJP, на странице 472 ("SCJP Sun Certified Programmer for Java 6 Exam 310-065.pdf"). Но не знаю, как проверить сиё: содержимое этого самого стринг-пула как-то можно вытряхнуть в виде дампа или еще чего-то ?
...
Рейтинг: 0 / 0
Генерация повторяющихся String-значений: работает ли при этом intern()-буфер ?
    #38273274
Фотография schwa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: java
1.
2.
3.
4.
5.
public class S {
  public static void main(String[] args) {
    String s = new String("abc");
  }
}


javap -c SCompiled from "S.java"
public class S {
public S();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return

public static void main(java.lang.String[]);
Code:
0: new #2 // class java/lang/String
3: dup
4: ldc #3 // String abc
6: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V
9: astore_1
10: return
}
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Генерация повторяющихся String-значений: работает ли при этом intern()-буфер ?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]