1

SimpleInjector のパフォーマンスと速度が非常に優れていることはわかっていますが、とにかく、Container.GetInstance() メソッドを呼び出すオーバーヘッドがどれほど大きいかを把握する必要があります。

たとえば、次のクラスがあるとします。

public class ServiceManager
{
    private static Container _services;

    public static void Initialize()
    {
        _services = new Container();
    }

    public static ICacheClient Cache 
    {
        get
        {
            return _services.GetInstance<ICacheClient>();
        }
    }

}

Cache プロパティが頻繁に使用されている場合、またはそれを削除してコンシューマーがコンテナを直接使用して ICacheClient のインスタンスを明示的に取得するようにしておく必要がある場合、パフォーマンスへの影響はどうなりますか?

4

1 に答える 1

2

誰もその質問に答えることはできません。パフォーマンスへの影響は、ハードウェア、アプリケーション、そのプロパティが呼び出される頻度など、多くの変数によって異なります。

したがって、本当の問題は、状況に応じて十分に高速かどうかです。これをベンチマークすることでわかるのはあなただけです。

このフレームワークは、次の点で高度に最適化されています。

  • GetInstance<T>フレームワークのハッピー パスでのメソッド呼び出しの数を最小限に抑えます (これは、および を呼び出すときのメソッド呼び出しの最小数を意味しますGetInstance(Type))。
  • アプリケーションのハッピー パスでのロックの数を最小限に抑えます (ハッピー パスは現在ロックフリーです)。
  • オブジェクト グラフを解決するときにコンテナーへのコールバックの数を最小限に抑えます (つまり、コンテナー自体はオブジェクトの依存関係を解決するために呼び出すのではなく、登録の内部で構築されたデリゲートGetInstance<T>でそれらの依存関係の作成をインライン化します)。Func<object>

ただし、Simple Injector は高度に最適化されていますが、呼び出しには一定のコストがかかりGetInstance<T>ます。各呼び出しで、コンテナーは常に次のことを行う必要があります。

  • Dictionary<Type, InstanceProducer>指定された に対して (現在の実装ではa を使用して) 辞書検索を行いtypeof(T)ます。
  • 見つかったインスタンスGetInstance()でメソッドを呼び出します。InstanceProducer
  • Func<object>指定されたインスタンス (InstanceProducer.GetInstanceメソッド内)を作成するためにデリゲートを呼び出します。
  • from から戻る前にobjecttoにキャストします。TGetInstance<T>

この一定のコストから、辞書検索の実行には約 80% の時間がかかります。ただし、特に大きなオブジェクト グラフを解決する場合は、シングルトン以外のものを解決し始めると、一定のオーバーヘッドの割合が急速に低下します。

それでも、Cacheアプリケーションのパフォーマンス クリティカル パスでプロパティを多数呼び出す場合は、それを最適化することをお勧めします (ただし、遅すぎるかどうかを判断する必要があります。時期尚早の最適化は行わないでください)。これを行う簡単な方法の 1 つはICacheClient、コンシューマーのコンストラクターに を注入することです。これにより、インスタンスがコンテナーから何度も解決されることがなくなり、コンシューマーはローカルにキャッシュされたICacheClientインスタンスを問題なく使用できるようになります。

実際のところ、これはコンストラクター インジェクションと呼ばれる一般的なパターンであり、推奨される実践です。GetInstance<T>リクエスト中にコンテナに絶えずコールバックするのではなく、「リクエスト」の開始時にを 1 回呼び出すことで、コンテナに完全なオブジェクト グラフを構築させる(コンストラクタ インジェクションを使用)ことをお勧めします。

于 2013-07-25T07:51:17.293 に答える