Прежде чем кто-либо задаст вопрос об использовании string.intern()
вообще, позвольте мне сказать, что мне это нужно в моем конкретном приложении по соображениям памяти и производительности. [1]
Итак, до сих пор я использовал string.intern()
и считал, что это самый эффективный способ сделать это. Тем не менее, я заметил, что с возрастом это узкое место в программном обеспечении. [2]
Затем, совсем недавно, я попытался заменить string.intern()
на огромную карту, где я помещал/получал строки, чтобы каждый раз получать уникальный экземпляр. Я ожидал, что это будет медленнее... но это было как раз наоборот! Это было намного быстрее! Замена intern()
путем нажатия/опроса карты (которая достигает точно такой же) привела к более чем на порядок быстрее.
Вопрос: почему intern()
так медленно?!? Почему же это не просто подкрепляется картой (или фактически, просто настроенным набором) и будет намного быстрее? Я озадачен.
[1]: для неубежденных: он обрабатывается на естественном языке и должен обрабатывать гигабайты текста, поэтому необходимо избегать многих экземпляров одной и той же строки, чтобы избежать раздувания памяти и сравнения ссылочных строк достаточно быстро.
[2]: без него (нормальные строки) это невозможно, при этом этот конкретный шаг остается наиболее интенсивным для вычисления
EDIT:
Из-за удивительного интереса к этому сообщению, вот какой-то код для его проверки:
И результаты интернирования бит более 1 миллиона строк:
-
HashMap
: 4 секунды -
string.intern()
: 54 секунды
Из-за того, что вы не используете кеширование разморозки /OS IO и прочее подобное, эксперимент повторялся путем инвертирования порядка обоих эталонных тестов:
-
string.intern()
: 69 секунд -
HashMap
: 3 секунды
Как вы видите, разница очень заметна, более десяти раз. (Используя OpenJDK 1.6.0_22 64 бит... но с помощью солнца один привел к аналогичным результатам, я думаю)