cyn*_*nic 15 .net c# clr jit ngen
我正在尝试优化我的应用程序,以便它在启动后立即运行良好.目前,它的发行版包含304个二进制文件(包括外部依赖项),总计57兆字节.它是一个主要进行数据库访问的WPF应用程序,没有任何重要的计算.
我发现Debug配置为大多数操作提供了更好的(~5倍增益)时间,因为它们是在应用程序进程的生命周期中第一次执行.例如,在应用程序中打开特定屏幕,NGENed Debug需要0.3秒,JITted Debug需要0.5秒,NGENed Release需要1.5秒,JITted Release需要2.5秒.
我知道JIT编译时间的差距是由JIT编译器对Release二进制文件应用更积极的优化引起的.从我可以告诉,调试和发布配置由不同/p:DebugType并/p:Optimize传递给C#编译器开关,但我看到,即使我建立与应用程序相同的性能差距/p:Configuration=Release /p:DebugType=full /p:Optimize=false-也就是说,相同的图像调试选项中/p:Configuration=Debug.
我确认通过查看DebuggableAttribute应用于生成的程序集来应用选项.观察NGEN输出,我看到<debug>添加到正在编译的一些程序集的名称 - NGEN如何区分调试和非调试程序集?正在测试的操作使用动态代码生成 - 动态代码应用了什么级别的优化?
注意:由于外部依赖性,我使用的是32位框架.我应该期待x64有不同的结果吗?
注意:我也不使用条件编译.因此,两种配置的编译源都是相同的.
好的,这里有几个问题。
\n\n\n\n\n据我所知,调试和发布配置因传递给 C# 编译器的\n /p:DebugType 和 /p:Optimize 开关而有所不同,但即使我使用\n / 构建应用程序,我\n 也看到了相同的性能差距p:Configuration=Release /p:DebugType=full /p:Optimize=false \xe2\x80\x93 也就是说,与 /p:Configuration=Debug 中的映像调试选项相同。
\n
尽管复选框是相同的,但更改为发布模式也会导致某些内部代码路径被删除,例如Debug.Assert()(在 Microsoft 内部代码中大量使用)。所以这些不会在运行时评估,这会导致一些性能提升。DebugType=full生成与其编译时所针对的代码相匹配的 PDB,因此本身不会影响性能。如果部署了 PDB,异常处理代码将使用 PDB 针对编译后的代码提供更有用的堆栈跟踪。发布模式还会在内部触发一些内存改进,因为调试版本用于附加调试器。
NGEN 是一种用于“潜在”优化应用程序的工具。它优化了特定于您所使用的计算机的代码。但它也有缺点,因为 JIT 编译器可以更改内存中代码的布局,而 NGEN 本质上更加静态。
\n\n至于 32 位 (x86) 依赖项,您的应用程序现在将以 x86 模式运行。如果依赖项有 x86 和 x64 版本可用,并且您的应用程序在“任何 CPU”编译模式下编译,则 JIT 编译器将在 2 之间自动切换。NGEN 只会为当前计算机生成特定版本。因此,如果您使用 NGEN 然后进行分发,它只会适用于您编译的特定架构。
\n\n如果您没有使用条件编译功能,那么从“调试”切换到“发布”并不重要。但您会在发布中看到性能优势。
\n\n对于 NGEN,我建议您进行广泛的测试,以了解 NGEN 相对于 2 的优势。它并不总是能带来更好的性能。
\n