你有没有用过ngen.exe?

问题描述 投票:47回答:8

这里有人曾经使用过ngen吗?哪里?为什么?是否有任何性能提升?何时何地使用它有意义?

c# .net optimization clr ngen
8个回答
19
投票

是的,我见过性能改进。我的测量表明,如果我也将我的程序集放入GAC,它确实提高了启动性能,因为我的程序集都是强名称。如果你的程序集名称很强,那么在不使用GAC的情况下,NGen不会有任何区别。这样做的原因是,如果您具有不在GAC中的强命名程序集,那么.NET运行时通过从磁盘加载整个托管程序集来验证您的强命名程序集未被篡改,以便它可以验证它是否可以绕过它NGen的主要好处之一。

这对我的应用程序来说不是一个很好的选择,因为我们依赖于我们公司的通用程序集(也是强名称)。许多使用许多不同版本的产品使用通用程序集,将它们放在GAC中意味着如果我们的某个应用程序没有说其中一个通用程序集的“使用特定版本”,它将加载GAC版本而不管是什么版本在其执行目录中。我们认为NGen的好处并不值得冒险。


30
投票

我不是每天都使用它,但它被想要提高性能的工具使用;例如,Paint.NET在安装过程中使用NGEN(或者可能是第一次使用)。有些MS工具也可以(虽然我不确定)。

基本上,NGEN执行大部分JIT以进行组装,因此冷启动几乎没有延迟。当然,在大多数典型的用法中,并没有达到100%的代码,所以在某些方面这会做很多不必要的工作 - 但它无法提前告诉我们。

IMO的缺点是你需要使用GAC来使用NGEN;我尽量避免使用GAC,这样我就可以使用robocopy-deployment(到服务器)和ClickOnce(到客户端)。


8
投票

Ngen主要减少.NET应用程序和应用程序工作集的启动时间。但它有一些缺点(来自CLR Via C#of Jeffrey Richter):

没有知识产权保护

NGen文件可能会失去同步

劣质负载时间性能(重新绑定/绑定)

劣质执行时间性能

由于刚刚列出的所有问题,在考虑使用NGen.exe时应该非常谨慎。对于服务器端应用程序,NGen.exe几乎没有任何意义,因为只有第一个客户端请求会遇到性能损失;未来的客户请求高速运行。此外,对于大多数服务器应用程序,只需要一个代码实例,因此没有工作集的好处。

对于客户端应用程序,如果多个应用程序同时使用程序集,则NGen.exe可能有助于缩短启动时间或减少工作集。即使在多个应用程序不使用组件的情况下,NGen的组装也可以改善工作组。此外,如果NGen.exe用于所有客户端应用程序的程序集,则CLR根本不需要加载JIT编译器,从而进一步减少了工作集。当然,如果只有一个程序集不是NGen或者无法使用程序集的NGen文件,那么JIT编译器将加载,并且应用程序的工作集会增加。


7
投票

ngen主要用于改善启动时间(通过消除JIT编译)。它可能会改善(通过减少JIT时间)或降低应用程序的整体性能(因为某些JIT优化将不可用)。

.NET Framework本身在安装时将ngen用于许多程序集。


1
投票

我用它但仅用于研究目的。如果您确定部署环境的cpu架构(它不会更改),请仅使用它

但是让我告诉你JIT编译并不是太糟糕,如果你在多个cpu环境中进行部署(例如经常更新的Windows客户端应用程序)那么就不要使用NGEN。因为有效的ngen缓存,它取决于许多属性。如果其中一个失败,你的组件会再次回到jit

在这种情况下,JIT是一个明显的赢家,因为它可以根据运行的cpu架构动态优化代码。 (例如,它可以检测是否有超过1个cpu)

每次发布时clr都会越来越好,所以简而言之,除非你对你的部署环境不确定,否则你最好坚持下去 - 即使这样你的性能提升也难以证明使用ngen.exe(可能会在几百毫秒内获得) - imho - 它不值得努力

还要查看关于此主题的真正好的链接 - JIT Compilation and Performance - To NGen or Not to NGen?


0
投票

是。用于WPF应用程序以加快启动时间。启动时间从9秒到5秒。在我的blog中了解它:

我最近发现NGEN在性能方面有多棒。我目前正在处理的应用程序具有生成的数据访问层(DAL)。数据库模式非常大,我们还直接在DAL中生成一些数据(值列表)。结果:许多具有许多字段的类和许多方法。在分析应用程序时经常出现JIT开销,但是在搜索JIT编译和NGEN之后我虽然不值得。安装时间开销,管理层我主要担心,让我忽略了标志,而是专注于为应用程序添加更多功能。当我们将架构更改为在64位计算机上运行的“任何CPU”时,事情变得更糟:我们在单个语句中经历了在应用程序中挂起长达10秒,并且探查器仅显示问题区域上的JIT开销。 NGEN解决了这个问题:声明从10秒到1毫秒。这个声明不是启动程序的一部分,所以我很想知道NGEN整个应用程序可以对启动时间做些什么。它从8秒到3.5秒。

结论:我真的建议您尝试使用NGEN!


0
投票

作为Mehrdad Afshari关于JIT编译的评论的补充。如果通过XmlSerializer和64位系统序列化具有许多属性的类,则SGEN,NGEN组合可能具有巨大的(在我们的情况下为千兆字节和分钟)效果。

更多信息:XmlSerializer startup HUGE performance loss on 64bit systems特别看到Nick Martyshchenko的回答。


0
投票

是的,我尝试使用一个小的单CPU密集的exe和ngen它稍慢!

我多次安装和卸载了ngen映像并运行了一个基准测试。

我总是得到以下时间可再现+/- 0.1s:33.9s没有,35.3s有

© www.soinside.com 2019 - 2024. All rights reserved.