第一次运行方法时,.NET Release代码非常慢。 如何用NGen解决它?

我已经在发布模式(x64)中部署了一个应用程序,我期望它很快,并且我注意到每当第一次执行新方法或一组方法时,都会出现严重的减速。 当我说严厉时,我的意思是第一次执行100-200毫秒,之后需要1毫秒。

从我发现的,这似乎是由于JIT编译器应该在第一次运行时编译方法。 我预计会有一些延迟,但是在执行过程中100毫秒是一个灾难性的延迟。

我知道NGen,但NGen需要在机器安装时完成。 这适用于所有人的机器具有有限的用户权限,无法安装任何东西。 该应用程序部署为可执行文件和引用DLL。 我想这就是为什么我永远不能让NGen工作的原因。

有没有办法让JIT在启动时编译每个方法?

我虽然创建虚拟变量并添加一个启动例程,除了运行每个方法一次之外什么也不做,所以它可以是启动完成时的内容。 这是否足以强制编译或者方法的每个代码路径都需要单独执行。

哇。 这种延迟对于JIT来说是不寻常的。 分析您的应用程序以确保瓶颈是JIT。

现在,如果它真的是JIT,这里有一个比在任何地方添加伪参数更好的方法:

对每个非generics方法使用RuntimeHelpers.PrepareMethod 。 该函数将强制JIT处理它。

您还可以在每个类上使用RunClassConstructor方法来…运行它们的静态构造函数。

这是一些(完全未经测试的)代码:

 foreach (var type in Assembly.GetExecutingAssembly().GetTypes()) { if (type.IsGenericTypeDefinition || type.IsInterface) continue; RuntimeHelpers.RunClassConstructor(type.TypeHandle); foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly)) RuntimeHelpers.PrepareMethod(method.MethodHandle); } 

应该在安装时在每台机器上运行NGen。 使其成为安装过程的一部分。 这将编译相关的架构。

如果您的延迟确实是由于JITting,那么这应该解决它。 配置您的应用程序以确保。

我的第一个解决方案是手动创建类的虚拟实例,然后使用可选的虚拟bool变量调用方法,默认情况下这将是false。 这工作但需要将这个假人添加到每个粗略且耗时的方法中。

Lucas Trzesniewski的答案远非如此,因为它准备了代码中的所有类和所有方法,并且它不需要对我的任何代码进行任何更改,因此它更容易实现。 唯一的代价是,通过如此彻底,需要更长的时间才能完成大约.5到1.5秒,或者比我的选择性启动时长0.5到1秒。 在我的情况下,不仅仅值得确保代码中不会发生延迟。

除了初始启动之外,内存或CPU使用率没有明显的峰值,内存使用率实际上略有下降,可能是因为所有代码现在都已经过编译和优化。