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