使用 NGen 提高启动性能

注意

仅限 EF6 及更高版本 - 此页面中讨论的功能、API 等已引入实体框架 6。 如果使用的是早期版本,则部分或全部信息不适用。

.NET Framework 支持为托管应用程序和库生成本机映像,以帮助应用程序更快启动,并且在某些情况下使用更少的内存。 本机映像使 .NET JIT(实时)编译器不必在应用程序运行时生成本机指令,因为它是通过以下方式创建的:在执行应用程序之前,将托管代码程序集转换为包含本机计算机指令的文件。

在版本 6 之前,EF 运行时的核心库是 .NET Framework 的一部分,系统会自动为其生成本机映像。 从版本 6 开始,整个 EF 运行时已合并到 EntityFramework NuGet 包中。 现在必须使用 NGen.exe 命令行工具生成本机映像,才能达到类似的效果。

经验观察表明,EF 运行时程序集的本机映像可以将应用程序启动时间缩短 1 到 3 秒。

如何使用 NGen.exe

NGen.exe 工具最基本的功能是为程序集及其所有直接依赖项“安装”(即,创建并保存到磁盘)本机映像。 下面介绍如何实现此目的:

  1. 以管理员身份打开“命令提示符”窗口。

  2. 将当前工作目录切换到要为其生成本机映像的程序集所在的位置:

    cd <*Assemblies location*>  
    
  3. 根据操作系统和应用程序的配置,你可能需要为 32 位体系结构、64 位体系结构或两者生成本机映像。

    对于 32 位运行:

    %WINDIR%\Microsoft.NET\Framework\v4.0.30319\ngen install <Assembly name>  
    

    对于 64 位运行:

    %WINDIR%\Microsoft.NET\Framework64\v4.0.30319\ngen install <Assembly name>  
    

提示

为错误的体系结构生成本机映像是一个非常常见的错误。 如果不确定,可以直接为适用于计算机中安装的操作系统的所有体系结构生成本机映像。

NGen.exe 还支持其他功能,例如卸载和显示已安装的本机映像、排队生成多个映像等。有关其用法的更多详细信息,请阅读 NGen.exe 文档

何时使用 NGen.exe

当你决定在基于 EF 版本 6 或更高版本的应用程序中为哪些程序集生成本机映像时,应考虑以下选项:

  • 主要 EF 运行时程序集 EntityFramework.dll:典型的基于 EF 的应用程序会在启动时或首次访问数据库时,执行此程序集中的大量代码。 因此,创建此程序集的本机映像将最大程度地提高启动性能。
  • 应用程序使用的任何 EF 提供程序程序集:通过生成这些程序集的本机映像,也可稍微缩短启动时间。 例如,如果应用程序使用 SQL Server 的 EF 提供程序,则需要为 EntityFramework.SqlServer.dll 生成本机映像。
  • 应用程序的程序集和其他依赖项NGen.exe 文档涵盖了选择为哪些程序集生成本机映像的一般标准、本机映像对安全性的影响、高级选项(例如“硬绑定”)、各种方案(例如在调试和分析方案中使用本机映像),等等。

提示

确保仔细衡量使用本机映像对应用程序启动性能和整体性能的影响,并将它们与实际需求进行比较。 虽然本机映像通常有助于提高启动性能,并在某些情况下减少内存使用,但并非所有方案都能同样受益。 例如,在稳态执行时(即,一旦应用程序使用的所有方法至少被调用一次),由 JIT 编译器生成的代码带来的性能提升实际上比本机映像略胜一筹。

在开发计算机中使用 NGen.exe

在开发过程中,.NET JIT 编译器将为经常更改的代码提供最佳总体权衡。 通过为编译的依赖项(例如 EF 运行时程序集)生成本机映像,可以在每次执行开始时缩短几秒钟,从而有助于加速开发和测试。

查找 EF 运行时程序集的绝佳位置是解决方案的 NuGet 包位置。 例如,对于使用 EF 6.0.2 和 SQL Server 并面向 .NET 4.5 或更高版本的应用程序,可以在命令提示符窗口(记住以管理员身份打开它)中键入以下命令:

cd <Solution directory>\packages\EntityFramework.6.0.2\lib\net45
%WINDIR%\Microsoft.NET\Framework\v4.0.30319\ngen install EntityFramework.SqlServer.dll
%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\ngen install EntityFramework.SqlServer.dll

注意

这充分利用了以下事实:默认情况下,为 SQL Server 的 EF 提供程序安装本机映像同时也会为主要 EF 运行时程序集安装本机映像。 这是因为 NGen.exe 可以检测到 EntityFramework.dll 是位于同一目录中的 EntityFramework.SqlServer.dll 程序集的直接依赖项。

在安装过程中创建本机映像

如此操作指南所述,WiX 工具包支持在安装过程中为托管程序集排队生成本机映像。 另一种方法是创建一个自定义安装任务来执行 NGen.exe 命令。

验证本机映像是否用于 EF

可以通过查找扩展名为“.ni.dll”或“.ni.exe”的加载程序集,来验证特定应用程序是否正在使用本机程序集。 例如,EF 的主要运行时程序集的本机映像称为 EntityFramework.ni.dll。 检查进程的已加载 .NET 程序集的一种简单方法是使用进程资源管理器

其他需要注意的事项

不应将创建程序集的本机映像与在 GAC(全局程序集缓存)中注册程序集混淆。 NGen.exe 允许为不在 GAC 中的程序集创建映像,事实上,使用特定 EF 版本的多个应用程序可以共享同一个本机映像。 虽然 Windows 8 可以为放置在 GAC 中的程序集自动创建本机映像,但 EF 运行时已优化为与应用程序一起部署,我们不建议将其注册到 GAC,因为这会对程序集解析和为应用程序提供服务等其他方面产生负面影响。