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 属性被大量使用或者我应该删除它并让消费者直接使用 Container 显式获取 ICacheClient 的实例,会对性能产生什么影响?

4

1 回答 1

2

没有人可以为你回答这个问题。性能影响取决于许多变量,例如您的硬件、应用程序以及调用该属性的频率。

所以真正的问题是,它对你的情况是否足够快。您是唯一可以通过基准测试找出答案的人。

该框架经过高度优化,它将:

  • GetInstance<T>最小化框架的happy path中的方法调用次数(即调用and时方法调用的最少次数GetInstance(Type))。
  • 最小化应用程序快乐路径中的锁数量(快乐路径当前是无锁的)。
  • 在解析对象图时,尽量减少对容器的回调次数(这意味着容器本身不会调用来解析对象的依赖关系,但会在注册的内部构造委托GetInstance<T>中内联这些依赖关系的创建)。Func<object>

但是,尽管 Simple Injector 进行了高度优化,但调用GetInstance<T>. 每次调用时,容器都必须:

  • Dictionary<Type, InstanceProducer>对给定的typeof(T).
  • 调用GetInstance()找到的InstanceProducer实例上的方法。
  • 调用一个Func<object>委托来创建给定的实例(在InstanceProducer.GetInstance方法内部)。
  • 在从回来之前做一个演员 from objectto 。TGetInstance<T>

从这个不变的成本来看,进行字典查找大约需要 80% 的时间。然而,当您开始解决除单例之外的任何其他内容时,尤其是在解决大对象图时,恒定开销的百分比会迅速下降。

尽管如此,如果您在Cache应用程序的性能关键路径中对属性进行大量调用,您可能希望对其进行优化(但同样,您必须确定它是否太慢:不要进行过早的优化)。一种简单的方法是将 注入ICacheClient消费者的构造函数中。这可以防止实例一次又一次地从容器中解析出来,并允许消费者只使用本地缓存的ICacheClient实例而不会出现问题。

事实上,这是一种称为构造函数注入的通用模式,是一种建议的做法。更喜欢让容器为您构建一个完整的对象图(通过使用构造函数注入),方法是GetInstance<T>在“请求”开始时进行一次调用,而不是在该请求期间不断地回调容器。

于 2013-07-25T07:51:17.293 回答