首页 文章

调试与发布性能

提问于
浏览
122

我遇到了以下段落:

在Visual Studio中编译代码时,IDE中的“调试与发布”设置对性能几乎没有差别......生成的代码几乎相同 . C#编译器并没有真正进行任何优化 . C#编译器只是吐出IL ...而在运行时它是执行所有优化的JITer . JITer确实具有调试/释放模式,这对性能产生巨大影响 . 但这并不能决定你是否运行项目的调试或发布配置,而是关闭是否附加了调试器 . “

来源是here,播客是here .

有人可以指导我一篇能够证明这一点的微软文章吗?

谷歌搜索“C#debug vs发布性能" mostly returns results saying " Debug有很多性能命中", "发布优化", and "不要部署调试到 生产环境 ” .

10 回答

  • 93

    部分正确 . 在调试模式下,编译器为所有变量发出调试符号,并按原样编译代码 . 在发布模式中,包括一些优化:

    • 未使用的变量根本没有编译

    • 如果证明它们是不变量,则编译器会从循环中取出一些循环变量
      在#debug指令下编写的

    • 代码不包含在内 .

    其余的由JIT决定 .

    编辑:完整的优化列表here礼貌Eric Lippert

  • 1

    没有任何文章可以“证明”任何有关性能问题的内容 . 证明关于变更对性能影响的断言的方法是尝试两种方式并在现实但受控制的条件下对其进行测试 .

    你问一个关于表现的问题,所以很明显你关心表现 . 如果您关心性能,那么正确的做法是设置一些性能目标,然后自己编写一个测试套件,跟踪您实现这些目标的进度 . 一旦你有了这样的测试套件,你就可以轻松地使用它来自己测试语句的真实性或虚假性,例如“调试版本更慢” .

    此外,您将能够获得有意义的结果 . “较慢”毫无意义,因为尚不清楚它是慢一毫秒还是二十分钟慢 . “在现实条件下慢10%”更有意义 .

    花点时间在网上研究这个问题, Build 一个回答问题的设备 . 通过这种方式,您将获得更准确的结果 . 你在网上看到的任何东西都只是猜测会发生什么 . 你自己收集的事实的原因,而不是其他人猜测你的程序可能会如何表现的原因 .

  • 9

    我无法对性能发表评论,但建议“不要将调试部署到 生产环境 ”仍然只是因为调试代码在大型产品中通常会有很多不同的东西 . 首先,您可能有调试开关处于活动状态,而另一件事可能会有额外的冗余完整性检查和调试输出不属于 生产环境 代码 .

  • 0

    msdn social

    没有详细记录,这是我所知道的 . 编译器发出System.Diagnostics.DebuggableAttribute的实例 . 在调试版本中,IsJitOptimizerEnabled属性为True,在发行版本中为False . 您可以使用ildasm.exe在程序集清单中看到此属性.JIT编译器使用此属性来禁用会使调试变得困难的优化 . 像循环不变的提升一样移动代码的那些 . 在选定的情况下,这可以在性能上产生很大的不同 . 虽然不常见 . 将断点映射到执行地址是调试器的工作 . 它使用.pdb文件和JIT编译器生成的信息,它为代码地址映射提供IL指令 . 如果您要编写自己的调试器,则可以使用ICorDebugCode :: GetILToNativeMapping() .

    由于禁用了JIT编译器优化,因此调试部署基本上会更慢 .

  • 3

    你读的内容非常有效 . 由于JIT优化,版本通常更精益,不包括调试代码(#IF DEBUG或[条件(“DEBUG”)]),最小的调试符号加载,并且通常不考虑更小的组件,这将减少加载时间 . 由于更广泛的PDB和加载的符号,在VS中运行代码时性能不同更明显,但如果单独运行它,性能差异可能不太明显 . 某些代码将比其他代码优化得更好使用与其他语言相同的优化启发式方法 .

    Scott对内联方法优化有一个很好的解释here

    请参阅this article,它简要解释了为什么ASP.NET环境中的调试和发布设置不同 .

  • 3

    关于性能以及调试器是否附加,您应该注意一件事,这让我们感到意外 .

    我们有一段代码,涉及许多紧密循环,似乎需要永远调试,但它自己运行得很好 . 换句话说,没有遇到问题的客户或客户,但是当我们进行调试时,它似乎像糖蜜一样运行 .

    罪魁祸首是其中一个紧密循环中的一个 Debug.WriteLine ,它会抛出数千条日志消息,这些日志消息会在一段时间内从调试会话中消失 . 似乎当连接调试器并监听这样的输出时,会产生开销,这会减慢程序的速度 . 对于这个特定的代码,它自己的运行时间为0.2-0.3秒,连接调试器时为30秒 .

    简单的解决方案,只需删除不再需要的调试消息 .

  • 6

    msdn网站......

    Release vs. Debug配置当您仍在处理项目时,通常会使用调试配置来构建应用程序,因为此配置使您可以在调试器中查看变量的值并控制执行 . 您还可以在发布配置中创建和测试构建,以确保您没有引入任何仅在一种类型的构建或另一种类型上显示的错误 . 在.NET Framework编程中,此类错误非常罕见,但它们可能会发生 . 当您准备将应用程序分发给最终用户时,请创建一个版本构建版本,该构建版本将小得多,并且通常比相应的调试配置具有更好的性能 . 您可以在“项目设计器”的“构建”窗格中或“构建”工具栏中设置构建配置 . 有关更多信息,请参阅构建配置 .

  • 1

    我最近遇到了性能问题 . 产品完整列表花费了太多时间,大约80秒 . 我调整了数据库,改进了查询,没有任何区别 . 我决定创建一个TestProject,我发现在4秒内执行了相同的过程 . 然后我意识到项目处于调试模式,测试项目处于发布模式 . 我将主项目切换到发布模式,产品完整列表只需4秒即可显示所有结果 .

    简介:调试模式比运行模式慢得多,因为它保持调试信息 . 您应该始终以Relase模式部署 . 如果包含.PDB文件,您仍可以获得调试信息 . 这样,您可以使用行号记录错误 .

  • 2

    调试和释放模式有所不同 . 有一个工具Fuzzlyn:它是一个使用Roslyn生成随机C#程序的模糊器 . 它在.NET核心上运行这些程序,并确保在调试和发布模式下编译时它们提供相同的结果 .

    使用此工具,它被发现并报告了许多错误 .

  • 60

    在很大程度上,这取决于您的应用程序是否受计算限制,并且并不总是很容易辨别,如Lasse的例子 . 如果我对它正在做什么有任何疑问,我会暂停几次并检查堆栈 . 如果有一些额外的东西,我并不真正需要,那就立即发现它 .

相关问题