15

パフォーマンステストを行っているライブラリを作成しています。その中で私は一度生成しDictionary<Type, X>ます。アイテムは現在ランダムな順序で挿入されています。辞書は、アプリケーションの存続期間中は変更されません。

その後、アイテムを検索するために頻繁に使用されます。ルックアップは、ライブラリの大きなボトルネックの1つです。

はい、私はマイクロ最適化していますが、学ぶことです。ルックアップパフォーマンスを取得するためのより良い方法があるかどうか疑問に思っていますか?

アップデート

dotTraceを使用してパフォーマンスを測定しました。レポート+dotTraceは自宅のコンピューターにあるので、ここにはレポートがありません(別の場所にアップロードされている可能性があります)。

ここにあるテストを使用しました: https ://github.com/danielpalme/IocPerformance

辞書の定義はここにあります:https ://github.com/jgauffin/Griffin.Container/blob/master/Source/Griffin.Container/ContainerBase.cs

(私は先週の金曜日にコンテナを作成しました、あまり期待しないでください)

Update2

パフォーマンスの内訳

Dictionary.TryGetValueResolve合計で101ms(合計251ms)かかります。これは、数値を正しく解釈した場合、40,2%になります。

4

2 に答える 2

2

Daniel Palme による IoC コンテナーのパフォーマンス ベンチマーク (他のものも同様) は、少し誤解を招く可能性があります。これは、ベンチマークがコンテナーからの非常に浅いオブジェクト グラフを解決するためです (ただし、コンテナー間のパフォーマンスの違いが大きいことは明確に示されています)。ほとんどのアプリケーション (DI を適切に使用する) には、多数のオブジェクトを含むオブジェクト グラフがあるため、これは非現実的です。これを行う場合、解決する必要があるのはルート オブジェクトのみです。コンテナーが適切に作成されている場合、これはDictionary<T,V>.TryGetValue、ほとんどの状況で (またはせいぜい数回)、(Web) 要求ごとに 1 回の呼び出ししかないことを意味します。このため、 のパフォーマンスはDictionary<T, V>実際には問題になりません。

Dictionary<T,V>where TKeyisのパフォーマンス コストの大部分はSystem.Type、指定された のハッシュ コードを生成するパフォーマンス コストに関係していると思いますType。を呼び出すたびにTryGetValue、を呼び出す必要Type.GetHashCode()があります。GetHashCode は仮想 (インライン化できない) であり、そのメソッドは他の 3 つの仮想メソッドを呼び出します。最後に、静的 (外部) 呼び出しが に対して行われRuntimeHelpers.GetHashCode(key)ます。

つまり、パフォーマンスを最適化しTypeて、をキーとして使用する特定の (非ジェネリックな) 辞書クラスを作成し、呼び出す代わりに を呼び出すType.GetHashCode()ことができますRuntimeHelpers.GetHashCode(key)

更新 (2013-04-05):

数か月前、私は維持している DI コンテナーのパフォーマンスを改善しようと試み、辞書の部分を最適化して遊んでいました。私は直接呼び出すRuntimeHelpers.GetHashCode(key)(そして仮想呼び出しをスキップする) 独自の辞書を作成しましたが、最終的にパフォーマンスの向上が非常に小さい (Palme のベンチマークで約 1%) ため、これらのコードの変更を元に戻すことにしました。したがって、私の現在の理解では、 の実際のパフォーマンス コストDictionary<Type, X>は実際には内部で発生するすべてのものですRuntimeHelpers.GetHashCode(key)

于 2012-05-14T12:25:21.673 に答える
2

型がコンパイル時に定義されている場合は、次のように実装してみてください。

static class ValueFor<T>
{
  // you get another field per type T
  public static X X { get; private set; }

  internal static SetUpValue(X value) { X = value; }
}

これを使ってアクセスするだけです。

var myIntX = ValueFor<int>.X;
于 2012-05-14T10:30:07.263 に答える