c# - C# 编译器的图像调试选项如何影响 .NET JIT 编译性能(包括动态方法)?

标签 c# .net clr jit ngen

我正在尝试优化我的应用程序,使其在启动后立即运行良好。目前,它的发行版包含 304 个二进制文件(包括外部依赖项),总计 57 兆字节。它是一个 WPF 应用程序,主要执行数据库访问,没有任何重要的计算。

我发现调试配置为大多数操作提供了更好的(~5 倍增益)时间,因为它们是在应用程序进程的生命周期中首次执行的。例如,在 NGENed Debug 中打开应用内的特定屏幕需要 0.3 秒,JITted Debug 需要 0.5 秒,NGENed Release 需要 1.5 秒,JITted Release 需要 2.5 秒。

据我所知,JIT 编译时间的差距是由 JIT 编译器对发布二进制文件应用更积极的优化造成的。据我所知,调试和发布配置的不同之处在于 /p:DebugType。和 /p:Optimize传递给 C# 编译器的开关,但即使我使用 /p:Configuration=Release /p:DebugType=full /p:Optimize=false 构建应用程序,我也看到了相同的性能差距– 也就是说,与 /p:Configuration=Debug 中相同的图像调试选项.

我通过查看 DebuggableAttribute 确认应用了选项应用于生成的程序集。观察 NGEN 输出,我看到 <debug>添加到一些正在编译的程序集的名称中——NGEN 如何区分调试程序集和非调试程序集?正在测试的操作使用动态代码生成——什么级别的优化应用于动态代码?

注意:由于外部依赖,我使用的是 32 位框架。我应该在 x64 上期待不同的结果吗?

注意:我也不使用条件编译。因此两种配置的编译源是相同的。

最佳答案

如果如您所说,您有 304 个程序集要加载,那么这很可能是您的应用运行缓慢的原因。 这似乎是要加载的程序集数量非常多。

每次 CLR 从尚未加载到 AppDomain 中的另一个程序集获取代码时,它必须从磁盘加载它。

您可能会考虑使用 ILMerge 来合并其中的一些程序集。这将减少从磁盘加载程序集的延迟(您预先使用一个更大的磁盘)。

这可能需要一些实验,因为并不是所有的东西都喜欢被合并(特别是那些使用反射,并且依赖于程序集文件名永不改变的)。它还可能导致非常大的组件。

关于c# - C# 编译器的图像调试选项如何影响 .NET JIT 编译性能(包括动态方法)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10170602/

相关文章:

c# - 如何在多线程 C# 中使用 TCP 客户端/监听器?

.net - 除了必须总是自己编写之外,如何确保我们的函数在 F# 中使用缩写类型而不是基元?

c# - 是否可以使用 .net 检测来自 Windows 桌面应用程序的音频?

c# - 如何检查类型是否永远不是有效的泛型参数?

c# - 为什么在C#中int的Size具体是4字节?

c# - OutOfMemoryException - 如何发现内存泄漏?

c# - 序列化 ASPX 页面?

c# - 如何使用 C# 编辑文本文件?

C# 垃圾收集事件根

c# - 在由多个 View 模型绑定(bind)的 View 中绑定(bind)图像不起作用