【发布时间】:2012-04-16 08:08:18
【问题描述】:
我正在尝试优化我的应用程序,使其在启动后立即运行良好。目前,它的发行版包含 304 个二进制文件(包括外部依赖项),总计 57 兆字节。它是一个 WPF 应用程序,主要进行数据库访问,没有任何重要的计算。
我发现调试配置为大多数操作提供了更好的时间(约 5 倍增益),因为它们是在应用程序进程的生命周期中首次执行的。例如,NGENed Debug 需要 0.3 秒,JITted Debug 需要 0.5 秒,NGENed Release 需要 1.5 秒,JITted Release 需要 2.5 秒。
我了解 JIT 编译时间的差距是由 JIT 编译器对 Release 二进制文件应用更积极的优化造成的。据我所知,调试和发布配置因传递给 C# 编译器的 /p:DebugType 和 /p:Optimize 开关而异,但即使我使用 /p:Configuration=Release /p:DebugType=full /p:Optimize=false 构建应用程序,我也看到相同的性能差距——也就是说,相同图像调试选项,如/p:Configuration=Debug。
我通过查看应用于生成的程序集的DebuggableAttribute 来确认选项已应用。观察 NGEN 输出,我看到 <debug> 添加到正在编译的某些程序集的名称中 - NGEN 如何区分调试程序集和非调试程序集?正在测试的操作使用动态代码生成 - 对动态代码应用了什么级别的优化?
注意:由于外部依赖,我使用的是 32 位框架。我应该在 x64 上期待不同的结果吗?
注意:我也不使用条件编译。所以编译后的源码对于两种配置都是一样的。
【问题讨论】:
-
由于您的 Release NGENed 程序集仍然比 Debug 慢,您确定 JIT 是问题吗?你可以试试探查器……另外,检查你的代码中没有使用#if DEBUG。
-
您使用的是没有 SGEN 的 XmlSerializer 吗? stackoverflow.com/questions/771727/…
-
我没有使用
#if DEBUG(已编辑问题以反映这一点)。应用程序在发布时不一定较慢 - 它甚至可能更快,但我正在测量冷启动时间,而不是吞吐量。我怀疑动态方法的 JITting,所以我问是什么决定了这些方法的优化级别。 -
这一切都没有意义。这些是 warm 启动数字,ngen 使冷启动变慢。我想你应该尝试明确地使用 [Debuggable] 属性。
-
@HansPassant - 你是什么意思?我给出的时间测量如下:在应用程序加载并出现欢迎屏幕(“启动板”)后,单击一个磁贴,并计算时间,直到出现请求的屏幕。这对我来说是“冷”启动。 “温暖”是当我单击“返回”(该应用程序是基于导航的)并再次单击同一个图块时(我的代码没有“缓存”屏幕)。 “温暖”的表现在所有配置中都令人满意。