Pull to refresh
24
0
Владимир Долженко @vladimir_dolzhenko

Пользователь

Send message

Спасибо за ссылку. Берём jmh benchmark из JVM Anatomy Park #10: String.intern() и java 11 (build 11+28) запускаем — смотрим


Benchmark               (size)    Score     Error   Units
StrInt.chm               10000  2000,237 ± 73,646   ops/s
StrInt.chm:·gc.time      10000   100,000               ms
StrInt.intern            10000   448,418 ± 12,227   ops/s
StrInt.intern:·gc.time   10000    30,000               ms
StrInt.chm             1000000    10,792 ±  1,219   ops/s
StrInt.chm:·gc.time    1000000    33,000               ms
StrInt.intern          1000000     2,433 ±  0,218   ops/s
StrInt.intern:·gc.time 1000000    47,000               ms

для случая, когда нужна дедупликация intern() (а ведь именно на этот use-case по сути указывал автор статьи) — плохой выбор.

Окей — какие перформанс проблемы есть у intern с точки зрения его использования самой jvm? никаких — раньше был один размер таблицы — с увеличением внутренних нужд эту внутреннюю кухню чуть расширили.
А т.к. она не предназначена для работы вне jvm — то и проблемы индейцев инженеров jvm тоже не волнуют.
Оно не сломано, просто вы его не правильно готовите.

Это торчащая наружу ручка от самой JVM и Вам туда не надо — если сильно надо — то можно подкрутить размер hash table. Точка.

@Deprecated так на него и не навесили.

Данная тема, intern(), является настолько избитой, что кажется странно о ней уже говорить снова и снова.


Как минимум странно говорить о ней, когда это уже 2ая часть подобной статьи, и в 1ой части не могли не сослаться (пусть и в комментариях) на доклад Алексея Шипилёва


The Lord of the Strings https://www.youtube.com/watch?v=HWkVJkoo1_Q


и, конечно же, Катехизис: java.lang.String https://youtu.be/SZFe3m1DV1A?t=1913 — здесь я специально привёл момент, где подробно и в деталях рассказывают почему intern() это зло.


+ чуть ниже я привёл ссылку на проблему с которой можно столкнуться при использовании jackson (а если у вас есть REST API или вы как-то работаете со json — то скорее всего вы столкнётесь именно с ним): https://github.com/FasterXML/jackson-core/issues/332
Почитайте и посмотрите какие проблемы (на пустом месте) и лишние доп. расходы всплывают при этом (и не у меня одного — этот prod профиль фееричен), но автору jackson эти доводы не зашли (сразу).


+ нельзя не упоминуть JVM Anatomy Park (всё того же А. Шипилёва) и в частности, что касается intern(): JVM Anatomy Park #10: String.intern()


Можно ещё добавить про то, что intern hash table, которая реализована на уровне VM не расширяется. Ещё в бытность java 6 проводил эксперимент с intern и пересборкой java из сорсов, но это меркнет на фоне докладов и статей Шипилёва.


Надеюсь, что, теперь у вас есть более развёрнутый ответ на данную тематику и вы будете нести свет другим.

Некогда пытался убедить о вреде использования `intern()` в jason и что из этого вышло (спойлер — ничего хорошего)

https://github.com/FasterXML/jackson-core/issues/332

Не делайте String#intern(). Н И К О Г Д А.

Надеюсь не сильно перевру если опишу историю кратко — JEP делал не безызвестный Алексей Шипилёв — и что согласно профилям приложений который активно работали с не latin-1 строками (имена не назывались, но представьте себе региональные социальные сети) — и даже в их случае количество latin-1 строк было достаточно высокое (не 50%, но и не 10%). Среди прочего это и внутри vm вещи — имена классов и т.п.

Почему не бит — вопрос в том как его хранить с кем его есть — опять же — бенчмарки показали, что так (с флагом) будет лучше.
с чего вдруг взялась кодировка utf-8? мне вот по душе koi8r
не уверен как в таком виде их можно смёржить в основной репо.
В старом посте упоминаются A Heap of Trouble: G1:

LUCENE-6098: Indexwriter changecount assertion fail with g1gc и целый список от Lucene:

Do not, under any circumstances, run Lucene with the G1 garbage collector. Lucene's test suite fails with the G1 garbage collector on a regular basis, including bugs that cause index corruption.


Учитывая то, что баг ( bugs.openjdk.java.net/browse/JDK-8038348 ) на который ругаются таки закрыли — сейчас идёт long run test на G1 и если новых проблем не будет — то партия даст добро.
С GCG1 на ранних сборках 8ки (и кажется даже 10ки) наблюдали забавные глюки — собственно поэтому официально этот сборщик не поддерживается, но в планах его включить т.к. CMS уже помечен как deprecated в 10ке, и Oracle/OpenJDK настоятельно рекомендуют именно G1.
Про лимит документов — это общая проблема Lucene-based движков. Elastic в этом не одинок.
Понятно, что может — никто из этого никого секрета не делает — open source же. Я про то, что из коробки нельзя вытащить отдельные файлы snapshot'а — в силу специфики Lucene там могут оказаться куски предыдущего snapshot'а, которые мешать не будут, но будут занимать место.

Забавно, но буквально сегодня клиент спрашивал — как вытащить последний snapshot из кучи. Может стоит оформить ticket?
Согласен, но в целом ES уделяет большое внимание backward-compatibility, и braking changes по возможности делать как можно меньше — если только уже совсем никак. Но и старый воз костылей не хочется ни тащить, ни поддерживать.
В каком смысле
6я версия обратно не совместима с 5й.
?

Есть ломающие изменения (breaking changes), которые опять-таки описаны — но в целом 6ка должна читать индексы 5ки.
Про 32Гб достаточно подробно описано в документации и о том насколько именно надо быть меньше 32х Гб даже в зависимости от версии java.
в частном случае да, но в общем случае snapshot'ы инкрементальны
а если быть ещё точнее — начиная с 8ки (или 7ки?) — то если уровень коллизий больше некоторого числа (8-10) и ключ Comparable — то там будет вообще красно-чёрное дерево!
Я бы поспорил про ленивую инициализацию ArrayList / HashMap — начиная с какого-то билда 8ки — с конструктором по-умолчанию они внутри пустые — т.е расход только идёт на объект-обёртку (16байт?) но нет головных болей с null-reference и прочим усложнением lazy initialization.

Если уж так хочется экономить на спичках — то стоит ещё вспомнить про autoboxing — и что это ещё тот overhead — как по памяти, так и по производительности (derefence тоже не бесплатный) — и есть для этого специализированные коллекции — trove, koloboke, eclipse collections etc.

И самое главное, что кажется тут возможно подразумевается, но упущено — можно было сделать ArrayList, который бы всегда ужимался — но тогда будет страдать производительность, можно использовать TreeMap вместо HashMap (что фактически сделано в c++ с std::map) — это разумный trade-off — вы уж выбирайте — шашечки или ехать.

Согласен, что если так сильно запаривает память — то выделяй для ArrayList размер (если он известен), после можно делать trimToSize, или вызывать copy-ctor — это и для ArrayList/HashMap/CHM/HashSet и т.п справедливо.

Information

Rating
Does not participate
Location
Leiderdorp, Zuid-Holland, Нидерланды
Registered
Activity