少し前にストリングスとさまざまな言語について話し合っていたときに、ストリングスのインターンの話題が持ち上がりました。Java と .NET フレームワークは、すべての文字列といくつかのスクリプト言語でこれを自動的に行うようです。理論的には、同じ文字列の複数のコピーが作成されないため、メモリを節約できます。また、文字列の等価比較は、文字列の各文字を O(N) で実行するのではなく単純なポインター比較であるため、時間を節約できます。
しかし、考えれば考えるほど、そのコンセプトのメリットについて懐疑的になります。利点はほとんど理論的なものであるように私には思えます:
- まず、自動文字列インターニングを使用するには、すべての文字列が不変である必要があります。これにより、多くの文字列処理タスクが必要以上に難しくなります。(そして、はい、一般的に不変性に関するすべての議論を聞いてきました。それは重要ではありません。)
- 新しい文字列が作成されるたびに、少なくとも O(N) 操作である文字列インターニング テーブルに対してチェックする必要があります。(編集:ここで、N は文字列のサイズであり、テーブルのサイズではありません。これは人々を混乱させるためです。)したがって、新しい文字列の作成に対する文字列の等価性の比較の比率がかなり高くない限り、節約される正味の時間はそうではありません。正の値。
- 文字列等価テーブルが強い参照を使用している場合、不要になった文字列はガベージ コレクションされないため、メモリが浪費されます。一方、テーブルが弱い参照を使用している場合、文字列クラスはテーブルから文字列を削除するために何らかのファイナライザーを必要とするため、GC プロセスが遅くなります。(文字列インターン テーブルの実装方法によっては、これは非常に重要な場合があります。最悪の場合、ハッシュ テーブルから項目を削除すると、特定の状況下でテーブル全体の O(N) 再構築が必要になる場合があります。)
これは、実装の詳細について考えた結果です。見逃したものはありますか?文字列のインターンは実際に一般的なケースで大きなメリットをもたらしますか?
編集 2: わかりました、どうやら私は間違った前提から操作していたようです。私が話していた人は、ストリングインターンが新しく作成されたストリングのオプションであることを指摘したことはなく、実際には逆であるという印象が強かった. 問題を解決してくれたジョンに感謝します。彼のために別の受け入れられた答え。