在有人对使用 string.intern()
提出质疑之前,先说一下:出于内存和性能方面的原因,我需要在特定应用中使用它。[1]
到目前为止,我一直使用 String.intern()
并认为这是最有效的方法。然而,我注意到自从很久以前就成为了软件中的瓶颈。[2]
然后,最近我试图使用一个巨大的映射来代替 String.intern()
,在其中放置/获取字符串,以便每次获得唯一实例。我预计这会更慢... 但事实上却完全相反!它非常快!将 intern()
替换为推送/轮询映射(实现完全相同)导致速度提高了一个数量级以上。
问题是:为什么 intern()
如此缓慢?!为什么它不被简单地支持映射(或实际上只是定制集合)并且速度非常快呢?我感到困惑。
[1]:对于那些不信服的人:它用于自然语言处理,并且必须处理吉字节的文本,因此需要避免许多相同字符串的实例以避免内存剧增,而引用字符串比较必须足够快。
[2]:没有它(普通字符串)是不可能的,使用它后,这一特定步骤仍然是计算密集型的。
编辑:
由于此帖子的意外关注,在此提供一些代码进行测试:
并且将超过 1 百万个字符串的情况放入 intern()
的结果如下:
HashMap
:4 秒String.intern()
:54 秒
为了避免一些热身/操作系统IO缓存等问题,实验通过交换两个基准测试的顺序来重复进行:
String.intern()
: 69秒HashMap
: 3秒
如您所见,两者差异非常明显,超过10倍。(使用OpenJDK 1.6.0_22 64位……但我认为使用sun版本的结果类似)
intern
和同步的Hashtable
还是非同步的HashMap
进行比较?intern
是同步的,这可能是你观察到的很大一部分原因。 - Chris Dodd