|
|
|
Генерация повторяющихся String-значений: работает ли при этом intern()-буфер ?
|
|||
|---|---|---|---|
|
#18+
Здравствуйте. В следующем примере в цикле генерятся одни и те же 10 строк, каждая по 1 млн раз: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. Эта штука отрабатывает за ~7 сек. Для сравнения, то же самое через StringBuilder: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. - отрабатывает за 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. - улучшила время более чем в два раза (2625 vs 6922 ms), но всё равно хотелось бы понять, есть ли возможность задействовать внутренний буфер строк в таких случаях, как показано выше. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.05.2013, 16:28:06 |
|
||
|
Генерация повторяющихся String-значений: работает ли при этом intern()-буфер ?
|
|||
|---|---|---|---|
|
#18+
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 компиляции могут показать ещё более удивительные результаты. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.05.2013, 19:04:23 |
|
||
|
Генерация повторяющихся String-значений: работает ли при этом intern()-буфер ?
|
|||
|---|---|---|---|
|
#18+
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 байт. КМК. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.05.2013, 19:43:40 |
|
||
|
Генерация повторяющихся String-значений: работает ли при этом intern()-буфер ?
|
|||
|---|---|---|---|
|
#18+
ozzmosisКМК. Домыслы - источник заблуждений. Во-первых строки - Unicode, а не ASCII. Во-вторых заходим в класс String видим какие-то поля помимо char[] (зависит от версии Java) В-третих Java объект сам по себе имет некий заголовок ненулевого размера. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.05.2013, 19:48:29 |
|
||
|
Генерация повторяющихся String-значений: работает ли при этом intern()-буфер ?
|
|||
|---|---|---|---|
|
#18+
Подниму-ка тему. Допустим, прога читает строки из текстового файла (скажем, "Войну и Мир"). И каждую такую строку присваивает одной и той же String-переменной `s`. Вопрос: будет ли в итоге string pool (в предположении, что он достаточного размера) содержать уникальный список прочитанных строк ? То есть, если далее я попробую создать новую переменную String s2 = "Пьер Безухов" - будет в строковом буфере эта строка ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2013, 17:36:51 |
|
||
|
Генерация повторяющихся String-значений: работает ли при этом intern()-буфер ?
|
|||
|---|---|---|---|
|
#18+
ozzmosisПодниму-ка тему. Допустим, прога читает строки из текстового файла (скажем, "Войну и Мир"). И каждую такую строку присваивает одной и той же String-переменной `s`. Вопрос: будет ли в итоге string pool (в предположении, что он достаточного размера) содержать уникальный список прочитанных строк ?? Там не будет ничего. Ибо все строки будут создаваться через new String(...). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2013, 18:28:11 |
|
||
|
Генерация повторяющихся String-значений: работает ли при этом intern()-буфер ?
|
|||
|---|---|---|---|
|
#18+
schwaТам не будет ничего. Ибо все строки будут создаваться через new String(...).это если к ним далее не применять intern() ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2013, 18:45:51 |
|
||
|
Генерация повторяющихся String-значений: работает ли при этом intern()-буфер ?
|
|||
|---|---|---|---|
|
#18+
PS. Вроде как нашел ответ в ководстве по сдаче SCJP, на странице 472 ("SCJP Sun Certified Programmer for Java 6 Exam 310-065.pdf"). Но не знаю, как проверить сиё: содержимое этого самого стринг-пула как-то можно вытряхнуть в виде дампа или еще чего-то ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2013, 18:53:11 |
|
||
|
Генерация повторяющихся String-значений: работает ли при этом intern()-буфер ?
|
|||
|---|---|---|---|
|
#18+
Код: java 1. 2. 3. 4. 5. 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 } ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2013, 19:26:26 |
|
||
|
|

start [/forum/topic.php?fid=59&fpage=227&tid=2129287]: |
0ms |
get settings: |
19ms |
get forum list: |
30ms |
check forum access: |
8ms |
check topic access: |
8ms |
track hit: |
53ms |
get topic data: |
24ms |
get forum data: |
6ms |
get page messages: |
89ms |
get tp. blocked users: |
3ms |
| others: | 325ms |
| total: | 565ms |

| 0 / 0 |
