52

.Net フレームワーク固有の文字列インターンのプロセスと内部構造を知りたいです。また、インターニングを使用する利点と、パフォーマンスを向上させるために文字列インターニングを使用する必要があるシナリオ/状況についても知りたいです。Jeffery Richter の CLR の本からインターンについて学びましたが、まだ混乱しており、詳しく知りたいと思っています。

[編集] 以下のようなサンプル コードで特定の質問をする:

private void MethodA()
{
    string s = "String"; // line 1 - interned literal as explained in the answer        

    //s.intern(); // line 2 - what would happen in line 3 if we uncomment this line, will it make any difference?
}

private bool MethodB(string compareThis)
{
    if (compareThis == "String") // line 3 - will this line use interning (with and without uncommenting line 2 above)?
    {
        return true;
    }
    return false;
}
4

5 に答える 5

38

一般に、インターンは、リテラル文字列値を使用するときに自動的に発生するものです。Interning には、使用頻度に関係なく、メモリ内にリテラルのコピーが 1 つしかないという利点があります。

そうは言っても、実行時に生成された独自の文字列をインターンする理由があることはめったにありません。また、通常の開発のために文字列インターンを考えることさえありません。

潜在的に同一のランタイム生成文字列の比較で多くの作業を行う場合、潜在的にいくつかの利点があります (interning は ReferenceEquals を介して比較を高速化できるため)。ただし、これは非常に特殊な使用法であり、かなりの量のプロファイリングとテストが必要であり、測定された問題がない限り、最適化を検討することはできません。

于 2011-11-08T17:23:15.013 に答える
24

Interning は内部実装の詳細です。ボクシングとは異なり、リヒターの本で読んだ以上のことを知っていても、何のメリットもないと思います。

文字列を手動でインターンするマイクロ最適化の利点は最小限であるため、一般的にはお勧めしません。

これはおそらくそれを説明しています:

class Program
{
    const string SomeString = "Some String"; // gets interned

    static void Main(string[] args)
    {
        var s1 = SomeString; // use interned string
        var s2 = SomeString; // use interned string
        var s = "String";
        var s3 = "Some " + s; // no interning 

        Console.WriteLine(s1 == s2); // uses interning comparison
        Console.WriteLine(s1 == s3); // do NOT use interning comparison
    }
}
于 2011-11-08T17:22:38.423 に答える
23

これは「古い」質問ですが、私は別の角度から考えています。

小さなプールから長期間有効な文字列を大量に取得する場合は、インターンによってメモリ効率を向上させることができます。

私の場合、別のタイプのオブジェクトが頻繁に再利用されるため、静的辞書にインターンしていました。これは、ディスクに永続化する前に高速キャッシュとして機能しました。

これらのオブジェクトのほとんどのフィールドは文字列であり、値のプールはかなり小さいです (とにかく、インスタンスの数よりもはるかに小さい)。

これらが一時的なオブジェクトである場合、文字列フィールドは頻繁にガベージ コレクションされるため問題になりません。しかし、それらへの参照が保持されていたため、メモリ使用量が蓄積し始めました (新しい一意の値が追加されていない場合でも)。

そのため、オブジェクトをインターンすることでメモリ使用量が大幅に削減され、インターン中に文字列値をインターンすることも大幅に削減されました。

于 2013-09-13T06:25:32.443 に答える