这里有人用过ngen吗?在哪里?为什么?是否有任何性能改进?何时何地使用它有意义?
8 回答
我不是每天都使用它,但它被想要提高性能的工具使用;例如,Paint.NET 在安装过程中使用 NGEN(或者可能是第一次使用)。一些 MS 工具也有可能(尽管我不确定)。
基本上,NGEN 预先为装配执行大部分 JIT,因此冷启动几乎没有延迟。当然,在最典型的用法中,不会达到 100% 的代码,所以在某些方面这会做很多不必要的工作——但它不能提前告诉你。
IMO 的缺点是您需要使用 GAC 才能使用 NGEN;我尽量避免使用 GAC,以便我可以使用 robocopy-deployment(到服务器)和 ClickOnce(到客户端)。
是的,我看到了性能改进。我的测量结果表明,如果我也将我的程序集放入 GAC,它确实提高了启动性能,因为我的程序集都是强命名的。如果您的程序集是强命名的,则 NGen 不会在不使用 GAC 的情况下产生任何影响。这样做的原因是,如果您有不在 GAC 中的强命名程序集,则 .NET 运行时通过从磁盘加载整个托管程序集来验证您的强命名程序集没有被篡改,因此它可以验证它绕过NGen 的主要优势之一。
这对我的应用程序来说不是一个很好的选择,因为我们依赖于我们公司的通用程序集(它们也是强命名的)。通用程序集被许多使用许多不同版本的产品使用,将它们放入 GAC 意味着如果我们的应用程序之一没有说“使用特定版本”的通用程序集之一,它将加载 GAC 版本,无论什么版本在其执行目录中。我们认为 NGen 的好处不值得冒险。
Ngen 主要减少 .NET 应用程序和应用程序工作集的启动时间。但它有一些缺点(来自 Jeffrey Richter 的 CLR 通过 C#):
没有知识产权保护
NGen 的文件可能会不同步
较差的加载时间性能(变基/绑定)
较差的执行时间性能
由于刚才列出的所有问题,您在考虑使用 NGen.exe 时应该非常谨慎。对于服务器端应用程序,NGen.exe 几乎没有意义,因为只有第一个客户端请求会受到性能影响;未来的客户请求高速运行。此外,对于大多数服务器应用程序,只需要一个代码实例,因此没有工作集优势。
对于客户端应用程序,如果多个应用程序同时使用程序集,NGen.exe 可能有助于缩短启动时间或减少工作集。即使在一个程序集没有被多个应用程序使用的情况下,NGen 一个程序集也可以改进工作集。此外,如果 NGen.exe 用于所有客户端应用程序的程序集,CLR 将根本不需要加载 JIT 编译器,从而进一步减少工作集。当然,如果只有一个程序集不是 NGen 的,或者如果一个程序集的 NGen 文件不能使用,JIT 编译器将加载,并且应用程序的工作集增加。
ngen
主要以改善启动时间(通过消除 JIT 编译)而闻名。它可能会改善(通过减少 JIT 时间)或降低应用程序的整体性能(因为某些 JIT 优化将不可用)。
.NET Framework 本身ngen
在安装时用于许多程序集。
我用过它,但只是为了研究目的。仅当您确定部署环境的 cpu 架构时才使用它(它不会改变)
但让我告诉你 JIT 编译还不错,如果你有跨多个 cpu 环境的部署(例如经常更新的 Windows 客户端应用程序),那么不要使用 NGEN。那是因为有效的 ngen 缓存取决于许多属性。如果其中一个失败,您的程序集会再次退回到 jit
在这种情况下,JIT 显然是赢家,因为它根据运行的 cpu 架构动态优化代码。(例如,它可以检测是否有超过 1 个 cpu)
并且 clr 在每个版本中都在变得更好,所以简而言之,除非您对部署环境非常确定,否则请坚持使用 JIT - 即使这样,您的性能提升也很难证明使用 ngen.exe 是合理的(可能会在几百毫秒内获得收益) - 恕我直言 -它不值得努力
还检查这个关于这个主题的真正好的链接 - JIT Compilation and Performance - To NGen or Not to NGen?
是的。用于 WPF 应用程序以加快启动时间。启动时间从 9 秒变为 5 秒。在我的博客中阅读它:
我最近发现 NGEN 的性能有多么出色。我目前处理的应用程序有一个生成的数据访问层 (DAL)。数据库模式非常大,我们还直接将一些数据(值列表)生成到 DAL 中。结果:具有许多字段和许多方法的许多类。分析应用程序时经常会出现 JIT 开销,但在搜索 JIT 编译和 NGEN 之后,我认为这不值得。安装时间开销以及管理是我的主要关注点,这让我忽略了这些迹象,而是专注于为应用程序添加更多功能。当我们将架构更改为在 64 位机器上运行的“任何 CPU”时,情况变得更糟:我们的应用程序在单个语句上挂起长达 10 秒,而分析器仅显示问题区域的 JIT 开销。NGEN 解决了这个问题:语句从 10 秒缩短到 1 毫秒。这个声明不是启动过程的一部分,所以我很想知道 NGEN 对整个应用程序的启动时间有什么影响。它从 8 秒变为 3.5 秒。
结论:我真的建议在您的应用程序上尝试一下 NGEN!
作为 Mehrdad Afshari 关于 JIT 编译的评论的补充。如果通过 XmlSerializer 序列化具有许多属性的类并在 64 位系统上使用 SGEN,则 NGEN 组合具有潜在的巨大影响(在我们的例子中是千兆字节和分钟)。
更多信息在这里: XmlSerializer 启动在 64 位系统上的巨大性能损失,尤其是看到 Nick Martyshchenko 的回答。
是的,我用一个小型的单个 CPU 密集型 exe 进行了尝试,使用 ngen 时它稍微慢了一点!
我多次安装和卸载 ngen 映像并运行基准测试。
我总是得到以下可重现的 +/- 0.1 秒:没有 33.9 秒,有 35.3 秒