3

編集:私はこの質問を誤った仮定に基づいています-私が行っていたジェネリック型インスタンスのルックアップは、実行時に作成されたジェネリック型で行われた場合と同じ作業になるということです。私のハーネスにあるものはコンパイラーがアクセスできるので、アドレスルックアップにコンパイルできます。.MakeGenericTypeが舞台裏で何をするのかまだかなり興味があります。

IDictionaryから値を取得することと、静的プロパティを持つ汎用型から値を取得することを簡単に比較しました。

100000000ルックアップの結果:

辞書:14.5246952一般的なタイプ:00.2513280

.NETは、Genericのインスタンスにすばやくマップするために、バックグラウンドでどのような魔法を使用していますか?ルックアップにはハッシュテーブルに似たものを使用する必要があると思いました。多分それはJITTEDになります...私は知りません!あなたは?

これが私のテストハーネスです-間違いだらけだと思いますので、修正が必要なものを教えてください!

void Main()
{
    var sw = new Stopwatch();
    var d = new Dictionary<Type, object>() 
    { 
     { typeof(string), new object() },
     { typeof(int), new object() } 

    };
    var stringType = typeof(string);
    var intType = typeof(int);
    sw.Start();
    for (var i = 0; i < 100000000; i++)
    {
        Debug.Assert(d[stringType] != d[intType]);
    }
    sw.Stop();
    sw.Elapsed.Dump();
    sw.Reset();

    Lookup<string>.o = new object();
    Lookup<int>.o = new object();
    sw.Start();
    for (var i = 0; i < 100000000; i++)
    {
        Debug.Assert(Lookup<string>.o != Lookup<int>.o);
    }
    sw.Stop();
    sw.Elapsed.Dump();
}

class Lookup<T>
{
    public static object o;
}
4

2 に答える 2

4

JITコンパイラは静的o変数のアドレスを知っています。ローダーヒープに割り当てました。ジェネリッククラスのメンバーであることは関係ありません。つまり、静的変数のアドレスを解決するためにランタイムルックアップは必要ありません。コンパイル時に実行されます。生成されたマシンコードは簡単です。

000000f8  mov         eax,dword ptr ds:[02785D0Ch] 
000000fd  cmp         eax,dword ptr ds:[02785D10h] 

ハードコードされたアドレスに注意してください。

于 2010-11-25T16:47:56.417 に答える
2

ジェネリックスへのマッピングはコンパイル時に行われると思いますが、辞書は実行時にルックアップを実行します。

于 2010-11-25T15:21:08.673 に答える