1.5本地代码生成器: NGen.exe
.NET Framework 配套提供的NGen.exe工具可以在应用程序安装到用户的计算机时將IL代码编译成本地代码,那么CLR的JIT编译器就不需要在运行時编译IL代码,这有助于提升应用程序的性能:
1. 加快应用程序的启动速度 因为不需要再花时间编译
2. 减小应用程序的工作集 NGen.exe将IL代码编译成本地代码,并将这些代码保存到一个单独的文件中,这个文件可以通过”内存映射”的方式,同时映射到多个进程地址空间中,使代码得到了共享,避免每个进程都需要一份单独的代码拷贝.
使用NGen.exe时,NGen.exe会新建一个只包含本地代码的程序集文件,这个文件存放位置是:C:\Windows\Assembly\NativeImages_v4.0.#####_64这样的一个目录下的文件夹中.目录名称会包含CLR版本号和Windows的版本号.每当CLR加载程序集文件时就会检查是否存在对应的本地文件,如果存在则会直接使用本地文件中编译好的代码,不需要在运行时进行编译.
优点:
1. 获得了托管代码的所有好处(垃圾收集,验证,类型安全等)
2. 没有托管代码(JIT编译)的所有性能问题
缺点:
1. 没有知识产权保护. 尽管生成了本地代码,但还是要同时发布包含IL和元数据的程序集,因为当CLR不能使用NGen生成的文件时,CLR会自动对程序集的IL代码进行JIT编译.
2. NGen生成的文件可能失去同步. CLR加载NGen生成的一个文件时,它会将编译好的代码的大量特征与当前执行环境(CLR版本,CPU类型,Windows版本,安全性等)比较,任何一个不匹配,NGen生成的文件就不能使用,就要用JIT编译器.注意:可以在更新模式运行NGen.exe(例如安装了.NET Framework的一个新的Service Pack,这个Service Pack的安装程序就会自动在更新模式中运行NGen.exe),为以前的NGen生成的所有程序集再次运行NGen.exe,使NGen生成的文件与新安装的CLR版本保持同步.
3. 较差的执行时性能. 编译代码时,NGen无法像JIT那样对最终执行环境做出许多假设,这会造成NGen.exe生成较差的代码. 如NGen不能优化特定CPU指令;静态字段只能间接访问,而不能直接访问,因为静态字段的实际地址只能在运行时确定.测试证明,相较于JIT编译的版本,NGen生成的某些应用程序在执行时反而要慢5%左右,所以若使用NGen来提升性能,必须仔细比较NGen版本和非NGen版本优劣再做选择.
NGen对于服务器端的应用程序的作用并不明显,对于客户端应用程序或许能起到点作用.