5

我试图解决一些启动时间问题。在做一些分析后,我发现主要的罪魁祸首是ClassProxyGenerator.GenerateCode。第一次每种类型需要400-600毫秒。因此,如果应用程序的入口点有8个依赖项(在一个链中)需要代理生成,那么应用程序的启动时间将增加4.8秒。这可能看起来不是很多,但对于用户来说,它看起来像年龄。DynamicProxy生成速度

任何建议,以改善这一点?

更新:

我可以重现的时间与以下控制台应用程序:

 var container = new WindsorContainer(); 
     container.Register(Component.For<Interceptor>()); // dummy IInterceptor...does nothing 
     container.Register(Component.For<IMyRepository, MyAbstractRepository>().Interceptors<Interceptor>()); 
     var t = DateTime.Now; 
     var instance = container.Resolve<IMyRepository>(); 
     Debug.WriteLine("Resolved in " + (DateTime.Now - t).TotalMilliseconds); 

输出某处550ms和750毫秒之间。

IMyRepository是30个实体类型(由T4模板生成)的存储库接口。它有31个IQueryables,31个保存重载和31个删除重载。 MyAbstractRepository是一个部分抽象类。它声明了相同的3 x 31个方法。

如果我删除所有保存和删除的方法和只留下31个IQueryables,不注册的抽象库

container.Register(Component.For<IMyRepository>().Interceptors<Interceptor>()); 

我仍然奔波250ms的初始产生。

这是一个非常非常快的机器......所以现实世界中的任何事情都可能比上面列出的数字慢。

+1

这是荒谬的 - 除非你的类型有成百上千的方法(或者你在20机器上运行代码),否则不应该如此。你可以创建孤立的复制? –

+0

我知道......并且它不是20年前的机器......它似乎是具有这种滞留(其他类型在5-10ms内产生)的特定类型的集合...我将隔离并提供代码示例。 – Jeff

+1

如果您的依赖项可以延迟使用,您可能可以隐藏虚拟代理后面的依赖关系图部分。看到这里的概念概述:http://blog.ploeh.dk/2011/03/04/ComposeObjectGraphsWithConfidence.aspx –

回答

1

您可能可以在不同的线程中执行代理初始化,以便在生成代理时应用程序本身可以继续初始化。考虑将它排入线程池。

另一种选择可能是将代理编译为持久化的程序集文件,然后将其保存到磁盘。这样做会显着降低首次运行后的启动时间。

我不知道为什么Castle的动态代理需要这么长时间才能初始化。我不使用它们,我通常直接发送代码(或者作为简单方法的LCG,并且通过完整的Reflection.Emit来完成实现)。即使产生数百种LCG方法,我也从未有过如此长时间的延迟。也许使用不同的方法/库(LinFu等)也可以解决这个问题。