为了账号安全,请及时绑定邮箱和手机立即绑定

调试和发布版本之间的性能差异

调试和发布版本之间的性能差异

MM们 2019-06-12 15:00:41
调试和发布版本之间的性能差异我必须承认,我通常不会在调试和释放配置在我的程序中,我通常选择使用调试配置,即使在客户端实际部署程序时也是如此。据我所知,如果不手动更改这些配置,唯一的区别是调试有.DEBUG常量定义,以及释放有.优化代码检查过了。所以我的问题有两个:这两种配置之间是否存在很大的性能差异。是否有任何特定类型的代码会导致性能上的巨大差异,或者它实际上并不那么重要?是否有任何类型的代码在调试可能在以下情况下失败的配置释放配置,或者您是否可以确定在调试在发行版配置下,配置也可以很好地工作。
查看完整描述

3 回答

?
MMMHUHU

TA贡献1834条经验 获得超8个赞

在发行版构建中,C#编译器本身并不会更改所发出的IL。值得注意的是,它不再发射NOP操作码,允许您在卷曲大括号上设置断点。最大的一个是内置在JIT编译器中的优化器。我知道它进行了以下优化:

  • 方法衬里。将方法调用替换为注入该方法的代码。这是一个很大的问题,它使属性访问器基本上是免费的。

  • CPU寄存器分配。局部变量和方法参数可以保存在CPU寄存器中,而不会(或不太频繁)存储回堆栈帧。这是一个很大的问题,因为它使得调试优化代码变得如此困难。并给出易挥发关键字的意思。

  • 数组索引检查消除。处理数组时的一个重要优化(所有.NET集合类都在内部使用数组)。当JIT编译器可以验证一个循环从不索引超出界限的数组时,它将消除索引检查。大的。

  • 循环展开。通过在主体中重复代码4次并减少循环,可以改进具有小体的循环。降低了分支成本,并改进了处理器的超标量执行选项。

  • 死代码消除。如if(False){/.../}被完全淘汰。这可能是由于不断的折叠和内衬。其他情况是JIT编译器可以确定代码没有可能产生副作用。这种优化使得分析代码变得如此棘手。

  • 代码提升。循环中不受循环影响的代码可以从循环中移出。C编译器的优化器将花费更多的时间来寻找提升的机会。然而,这是一个昂贵的优化,因为需要的数据流分析和抖动无法负担的时间,所以只有提升明显的情况。迫使.NET程序员编写更好的源代码并提升自己。

  • 常见的子表达式消除。x=y+4;z=y+4;变成z=x;在语句中非常常见,如DEST[ix+1]=src[ix+1];为可读性而编写,而不引入辅助变量。不需要妥协可读性。

  • 不断折叠。x=1+2;变成x=3;这个简单的示例被编译器提前捕获,但在JIT时发生,而其他优化使得这成为可能。

  • 复制传播。x=a;y=x;变成y=a;这有助于寄存器分配器做出更好的决定。这在x86抖动中是一个很大的问题,因为它几乎没有什么寄存器可以使用。让它选择正确的选择是Perf的关键。

这些是非常重要的优化,可以使太棒了例如,当您分析应用程序的Debug构建并将其与发布版本进行比较时,会有很大的不同。但真正重要的是,当代码处于关键路径时,您编写的5%至10%的代码其实影响您程序的Perf。JIT优化器不够聪明,无法预先知道什么是关键,它只能为所有代码应用“将其转换为11”拨号。

这些优化对程序执行时间的有效结果通常会受到其他地方运行的代码的影响。读取文件、执行dBASE查询等。JIT优化器使工作完全不可见。不过,它并不介意:)

JIT优化器是相当可靠的代码,主要是因为它已经被测试了数百万次。在程序的发布版本中出现问题是非常罕见的。但这确实发生了。x64和x86抖动在结构上都有问题。x86抖动存在浮点一致性问题,当浮点计算的中间部分保持在80位精度的FPU寄存器中,而不是在刷新到内存时被截断时,会产生微妙的不同结果。


查看完整回答
反对 回复 2019-06-12
?
长风秋雁

TA贡献1757条经验 获得超7个赞

  1. 是的,有许多性能差异,这些都适用于您的代码。调试很少进行性能优化,并且发布模式非常多;

  2. 只有依赖于DEBUG常数在发行版构建中可能执行不同的操作。除此之外,你不应该看到任何问题。

依赖于DEBUG常数是Debug.Assert()方法,该方法具有以下属性[Conditional("DEBUG)"]定义。这意味着它也依赖于DEBUG常量,而这并不包括在发行版构建中。


查看完整回答
反对 回复 2019-06-12
?
慕标琳琳

TA贡献1830条经验 获得超9个赞

这在很大程度上取决于应用程序的性质。如果您的应用程序是UI密集型的,您可能不会注意到任何不同,因为连接到现代计算机的最慢的组件是用户。如果您使用一些UI动画,您可能需要测试在调试构建中运行时是否会发现任何明显的滞后。

但是,如果您有许多计算量很大的计算,那么您会注意到差异(正如Pieter所提到的那样,差异可能高达40%,尽管这将取决于计算的性质)。

这基本上是一种设计上的权衡。如果您在调试版本下发布,那么如果用户遇到问题,您可以得到更有意义的跟踪,并且可以进行更灵活的诊断。通过在调试版本中发布,还可以避免优化器产生模糊。海生虫.


查看完整回答
反对 回复 2019-06-12
  • 3 回答
  • 0 关注
  • 587 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信