调试和发布之间有啥(性能)差异吗?
Posted
技术标签:
【中文标题】调试和发布之间有啥(性能)差异吗?【英文标题】:Is there any (performance) difference between Debug and Release?调试和发布之间有什么(性能)差异吗? 【发布时间】:2011-02-04 15:49:21 【问题描述】:我正在使用 mysql Connector .NET 加载帐户并将其传输到客户端。 考虑到要加载的帐户的子元素,此操作相当密集。
在调试模式下,加载帐户最多需要 1 秒。平均值为 500 毫秒。 在发布模式下,加载帐户需要 1 到 4 秒。平均为 1500 毫秒。
由于我的代码中没有#if DEBUG
指令等,我想知道差异来自哪里。
是否有我可以更改的项目构建选项?或者它是否与 MySql Connector .NET 有关,根据构建模式会有不同的行为?
编辑:蜱监测。
Debug (Average: 213000 ticks)
730000
320000
60000
50000
190000
130000
210000
180000
160000
110000
390000
270000
150000
190000
230000
210000
150000
200000
190000
140000
Release (Average: 4404500 ticks)
12940000
170000
180000
80000
80000
130000
120000
5060000
5090000
130000
50000
10430000
25160000
150000
160000
130000
17620000
10160000
100000
150000
比较:
发布时间是调试时间的 20 倍(平均比较)。
4,404,500 / 213,000 = 20
现在第一次操作确实比较长,但是一般来说,其他时间都是这样的。 有什么想法吗?
编辑 2:我添加了更广泛的测试来计算总时间。对于 50 个帐户加载,调试平均需要 4 秒,发布平均需要 40 秒。我开始对此感到非常绝望——这对我的应用程序来说是一个严重的性能问题。有没有人猜测如何解决这个问题?
【问题讨论】:
您如何记录加载帐户所需的时间?您是否在一个循环中多次执行该操作并取平均值?还是您每次都将应用程序作为新进程启动? 有一个区别,除了它通常是相反的,因为代码优化不会在调试模式 iirc 中发生。不过我可以肯定地说,在我从事的任何项目中,mysql .net 连接器从来没有像我自己那样表现过。 使用分析器。其他一切都在猜测。 我监控了时间。主要问题将在 1 秒内编辑完毕。 @Lazlo 更新了我的答案 - 也许是垃圾收集? 【参考方案1】:时间上的差异可能是由于加载操作所需的程序集的时间发生了变化。
在发布模式下,运行时可能不需要立即加载您的操作稍后才需要的程序集(因为为发布构建执行了各种优化)。因此,在调试模式下,可能会在您开始计时操作之前加载程序集,而在发布模式下,可能会在您开始计时操作后加载程序集。加载程序集的时间可能很长,具体取决于程序集的大小。当然,这两种情况下都必须加载程序集,并且只需要加载一次,因此后续在发布模式下运行可能会更快。
尝试在一个循环内多次执行您的操作并忽略第一次执行,以找到平均更少的启动开销。
更新:
有趣的是,与调试模式相比,发布模式的时间变化很大(发布模式的标准开发时间高出 100 倍)。在较低端,发布模式的时间与调试模式下的时间相当。您在问题中提到加载帐户是密集的,因为必须加载所有子元素。另一个区别可能是运行时决定执行垃圾收集的时间点。要进行测试,您可以尝试在每次操作后(在您的计时器之外)执行 System.GC.Collect()
,看看是否会改变。
更新: 如果您怀疑与锁定相关的行为可能会发生变化,您可以考虑在调试和发布模式下运行测试时使用 Windows 性能监视器来监视应用程序进程的各种 .NET CLR LocksAndThreads 计数器.也许您没有在某处正确释放锁并且执行被延迟,直到一些超时失效?如果是这样,我希望看到性能计数器报告的争用率增加。我不确定为什么这只会成为发布版本的问题(除非您在运行调试版本时实际使用调试器)。
【讨论】:
添加了垃圾收集器,没有改变结果。 我可以在回家后尝试您的第二种解决方案,但即便如此,我也不明白为什么它只会影响发布版本。我测试了所有命令行参数,它们完全一样,一个字符一个字符,都是一样的。【参考方案2】:应用程序属性设置中“构建”和“调试”选项卡上的所有内容都可能因构建配置而异。其中一些仅涉及编译阶段,不会影响运行时性能(允许不安全代码、错误和警告、将警告视为错误和 XML 文档文件)。其他人可能会有所作为。
我会记下配置之间不同的每个设置,然后更改每个设置以使配置匹配,并在每次更改之间进行测试。那么你应该能够找到问题的根源。
我会特别测试定义 DEBUG 常量、定义 TRACE 常量、条件编译符号、平台目标、优化代码、(在高级屏幕上)检查算术上溢/下溢、生成序列化程序集、启用非托管代码调试和启用Visual Studio 托管过程。
【讨论】:
我已经测试了所有我能找到的,虽然我找不到以下内容:目标平台、生成序列化程序集、启用非托管代码调试。此外,它似乎会影响每个锁定操作(“线程安全”)。我将不得不更多地研究它,但真正的区别在于调试和发布之间。在发布模式下,我得到了非常奇怪的结果,甚至是未知的数据包(我正在制作服务器)。我认为这可能是因为调试/发布中的锁定差异,但即便如此,我也不知道这是从哪里来的!我开始迫切需要一个解决方案。【参考方案3】:我想通了,我允许在我的一个依赖项构建中使用不安全的代码。 我仍然想知道它为什么会这样,但我得再深入研究一下。
感谢您的帮助!
【讨论】:
以上是关于调试和发布之间有啥(性能)差异吗?的主要内容,如果未能解决你的问题,请参考以下文章
带有 Windows 调试工具的 ADPlus.exe - 与 ADPlus vbscript 相比有啥功能差异