前段时间我正在讨论字符串和各种语言,字符串实习的话题出现了。显然,Java 和 .NET 框架会自动对所有字符串以及几种脚本语言执行此操作。从理论上讲,它可以节省内存,因为您最终不会得到同一个字符串的多个副本,并且它可以节省时间,因为字符串相等比较是一个简单的指针比较,而不是 O(N) 遍历字符串的每个字符。
但我想得越多,我就越怀疑这个概念的好处。在我看来,优势主要是理论上的:
- 首先,要使用自动字符串暂留,所有字符串都必须是不可变的,这使得很多字符串处理任务比它们需要的更难。(是的,我听过所有关于不变性的论点。这不是重点。)
- 每次创建新字符串时,都必须根据字符串实习表检查它,这至少是一个 O(N) 操作。(编辑:其中 N 是字符串的大小,而不是表的大小,因为这让人们感到困惑。)因此,除非字符串相等比较与新字符串创建的比率非常高,否则节省的净时间不太可能是一个正值。
- 如果字符串相等表使用强引用,则字符串在不再需要时将永远不会被垃圾回收,从而浪费内存。另一方面,如果表使用弱引用,则字符串类需要某种终结器来从表中删除字符串,从而减慢 GC 过程。(这可能非常重要,具体取决于字符串实习生表的实现方式。在最坏的情况下,从哈希表中删除一个项目可能需要在某些情况下对整个表进行 O(N) 重建。)
这只是我思考实现细节的结果。有什么我错过的吗?在一般情况下,字符串实习是否真的提供了任何显着的好处?
编辑 2:好吧,显然我是在错误的前提下进行操作的。与我交谈的人从未指出弦乐实习对于新创建的弦乐是可选的,实际上给人的强烈印象是相反的情况。感谢 Jon 把事情弄清楚了。另一个接受他的答案。