调试与发布性能
我遇到过以下段落:
“在 Visual Studio 中编译代码时,IDE 中的调试与发布设置对性能几乎没有影响……生成的代码几乎相同。 C# 编译器实际上并没有做任何优化。 C# 编译器只是输出 IL……而在运行时,JITer 会执行所有优化。 JITer 确实有调试/发布模式,这对性能产生了巨大的影响。但这并不能决定您是否运行项目的“调试”或“发布”配置,而是决定是否附加调试器。”
有人可以指导我阅读一篇可以真正证明这一点的 Microsoft 文章吗?
谷歌搜索“C# 调试与发布性能”大多会返回这样的结果:“调试对性能有很大影响”、“发布已优化”,以及“不要将调试部署到生产”。
I've encountered the following paragraph:
“Debug vs. Release setting in the IDE when you compile your code in Visual Studio makes almost no difference to performance… the generated code is almost the same. The C# compiler doesn’t really do any optimization. The C# compiler just spits out IL… and at the runtime it’s the JITer that does all the optimization. The JITer does have a Debug/Release mode and that makes a huge difference to performance. But that doesn’t key off whether you run the Debug or Release configuration of your project, that keys off whether a debugger is attached.”
The source is here and the podcast is here.
Can someone direct me to a Microsoft article that can actually prove this?
Googling "C# debug vs release performance" mostly returns results saying "Debug has a lot of performance hit", "release is optimized", and "don't deploy debug to production".
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
发布速度更快:我发现 RAM 数据处理和简单但大量的数学过程的性能提高了 2.4 倍。
我刚刚在我支持的工业流程优化程序中对此进行了测试。它在 NP 硬空间中搜索最佳处理情况,并在测试期间评估大约十亿种情况,一次评估 1-900 万个块。我针对很多场景运行了它并总结了时间,所以我的样本大约是一万亿次失败和大约一万亿次失败。整数数学运算。我的大部分数据都在 List<> 中和数组格式并访问这些元素需要很多时间。我每次调试/发布的总测试时间约为 50 分钟,而 20 分钟。
我不是在谈论 GUI 性能、服务器访问或磁盘访问,而是在 RAM 中处理大量数字。当然,如果一个程序大部分时间都花在等待用户或外部资源(服务器)上,那么差别就不那么大了,但对于 RAM/数组/数学数字处理来说,差别就很大了。
Release is faster: I see about a 2.4 times performance increase in RAM data handling and simple but numerous math processes.
I just tested this in a program I support for industrial process optimization. It searches an NP hard space for the best handling of situations, and will evaluate roughly a billion situations during a test, in blocks of 1-9 million at a shot. I ran it against a lot of scenarios and summed the time, so my sample was about one trillion flops & integer math operations. Most of my data was in List<> and array format and accessing the elements of these was a lot of the time. My total test time in each debug/release was about 50 minutes vs. 20 minutes.
I'm not speaking of GUI performance, server access, or disk access, and instead crunching a ton of numbers in RAM. Of course if a program spends most of its time waiting for users or outside resources (servers) then it's not as big of a difference, but for RAM/array/math number crunching it makes a big difference.
我只是解释一下我自己的经历。
我在健康行业从事多个企业级应用程序的工作。
我们确实测量了 Debug VS Release (VS 2019 .NET 4.7) 的性能
我们的大多数应用程序都是基于 Web 表单和 C# 的。
在我们的例子中,各种功能和页面的调试和发布之间的差异只有大约一秒(实际上不到1秒)。
现在我们的业务确实不关心这种差异,但是如果我正在处理一个处理市场库存的应用程序事务甚至毫秒都很重要,而这正是发布模式变得重要的地方。
I just explain my own experience.
I work in health industry on several enterprise level applications.
We did measure the performance of Debug VS Release (VS 2019 .NET 4.7)
Majority of our applications are Web forms and C# based.
The difference between debug and release for various functions and pages in our case was only about a second(in fact less than 1 second.)
Now our business really do not care about this difference, but If I was handling an application for handling Market Stock transactions then even milliseconds were important and that exactly where Release mode becomes important.
调试和发布模式有区别。有一个工具 Fuzzlyn:它是一个利用 Roslyn 生成随机 C# 程序的模糊器。它在 .NET core 上运行这些程序,并确保它们在调试和发布模式下编译时给出相同的结果。
通过这个工具,我们发现并报告了很多错误。
Debug and Release modes have differences. There is a tool Fuzzlyn: it is a fuzzer which utilizes Roslyn to generate random C# programs. It runs these programs on .NET core and ensures that they give the same results when compiled in debug and release mode.
With this tool it was found and reported a lot of bugs.
在很大程度上,这取决于您的应用程序是否受计算限制,并且并不总是很容易判断,如 Lasse 的示例所示。如果我对它正在做什么有任何疑问,我会暂停几次并检查堆栈。如果发生了一些我并不真正需要的额外事情,它会立即发现。
To a large extent, that depends on whether your app is compute-bound, and it is not always easy to tell, as in Lasse's example. If I've got the slightest question about what it's doing, I pause it a few times and examine the stack. If there's something extra going on that I didn't really need, that spots it immediately.
您应该注意一件事,关于性能以及是否附加调试器,这让我们感到惊讶。
我们有一段代码,涉及许多紧密的循环,似乎需要很长时间才能调试,但它本身运行得很好。换句话说,没有客户或客户遇到问题,但当我们调试时,它似乎像糖蜜一样运行。
罪魁祸首是其中一个紧密循环中的 Debug.WriteLine ,它会吐出不久前调试会话留下的数千条日志消息。似乎当附加调试器并侦听此类输出时,会产生一些开销,从而减慢程序速度。对于这个特定的代码,它本身的运行时间约为 0.2-0.3 秒,当附加调试器时,运行时间为 30 秒以上。
不过,解决方案很简单,只需删除不再需要的调试消息即可。
One thing you should note, regarding performance and whether the debugger is attached or not, something that took us by surprise.
We had a piece of code, involving many tight loops, that seemed to take forever to debug, yet ran quite well on its own. In other words, no customers or clients where experiencing problems, but when we were debugging it seemed to run like molasses.
The culprit was a
Debug.WriteLine
in one of the tight loops, which spit out thousands of log messages, left from a debug session a while back. It seems that when the debugger is attached and listens to such output, there's overhead involved that slows down the program. For this particular code, it was on the order of 0.2-0.3 seconds runtime on its own, and 30+ seconds when the debugger was attached.Simple solution though, just remove the debug messages that was no longer needed.
在 msdn 站点...
In msdn site...
我最近遇到了性能问题。产品完整列表花费了太多时间,大约 80 秒。我调整了数据库,改进了查询,没有任何区别。我决定创建一个 TestProject,我发现相同的过程在 4 秒内执行。然后我意识到该项目处于调试模式,而测试项目处于发布模式。我将主项目切换到发布模式,产品完整列表只用了 4 秒就显示了所有结果。
摘要: 调试模式比运行模式慢得多,因为它保留调试信息。您应该始终在发布模式下部署。如果包含 .PDB 文件,您仍然可以获得调试信息。例如,这样您就可以使用行号记录错误。
I recently run into a performance issue. The products full list was taking too much time, about 80 seconds. I tuned the DB, improved the queries and there wasn't any difference. I decided to create a TestProject and I found out that the same process was executed in 4 seconds. Then I realized the project was in Debug mode and the test project was in Release mode. I switched the main project to Release mode and the products full list only took 4 seconds to display all the results.
Summary: Debug mode is far more slower than run mode as it keeps debugging information. You should always deploy in Relase mode. You can still have debugging information if you include .PDB files. That way you can log errors with line numbers, for example.
你读到的内容非常有效。由于 JIT 优化,发布通常更加精简,不包括调试代码(#IF DEBUG 或 [Conditional("DEBUG")])、最小化调试符号加载,并且通常不考虑较小的程序集,这将减少加载时间。在 VS 中运行代码时,由于加载了更广泛的 PDB 和符号,性能差异更加明显,但如果独立运行,性能差异可能不太明显。某些代码会比其他代码优化得更好,并且它使用与其他语言相同的优化启发式方法。
Scott 在此处对内联方法优化有很好的解释
请参阅本文 简要解释了为什么在 ASP.NET 环境中调试和发布设置有所不同。
What you read is quite valid. Release is usually more lean due to JIT optimization, not including debug code (#IF DEBUG or [Conditional("DEBUG")]), minimal debug symbol loading and often not being considered is smaller assembly which will reduce loading time. Performance different is more obvious when running the code in VS because of more extensive PDB and symbols that are loaded, but if you run it independently, the performance differences may be less apparent. Certain code will optimize better than other and it is using the same optimizing heuristics just like in other languages.
Scott has a good explanation on inline method optimization here
See this article that give a brief explanation why it is different in ASP.NET environment for debug and release setting.
来自 msdn 社交
基本上,由于 JIT 编译器优化被禁用,调试部署会变慢。
From msdn social
Basically debug deployment will be slower since the JIT compiler optimizations are disabled.
我无法评论性能,但“不要将调试部署到生产中”的建议仍然有效,因为调试代码在大型产品中通常会做很多不同的事情。一方面,您可能会激活调试开关,另一方面,可能还会有不属于生产代码的额外冗余健全性检查和调试输出。
I can’t comment on the performance but the advice “don’t deploy debug to production” still holds simply because debug code usually does quite a few things differently in large products. For one thing, you might have debug switches active and for another there will probably be additional redundant sanity checks and debug outputs that don’t belong in production code.
没有任何文章可以“证明”有关性能问题的任何内容。证明变更对性能影响的断言的方法是尝试两种方法并在现实但受控的条件下进行测试。
您问的是有关性能的问题,所以显然您关心性能。如果您关心性能,那么正确的做法是设定一些性能目标,然后为自己编写一个测试套件来跟踪您针对这些目标的进度。一旦您拥有这样的测试套件,您就可以轻松地使用它来自己测试诸如“调试构建速度较慢”之类的陈述的真实性或虚假性。
此外,您将能够获得有意义的结果。 “慢”是没有意义的,因为不清楚是慢了一微秒还是慢了二十分钟。 “现实条件下慢10%”更有意义。
花一些时间在网上研究这个问题来构建一个可以回答这个问题的设备。这样你会得到更准确的结果。您在网上阅读的任何内容都只是对可能发生的情况的猜测。根据您自己收集的事实进行推理,而不是根据其他人对您的程序可能如何运行的猜测。
There is no article which "proves" anything about a performance question. The way to prove an assertion about the performance impact of a change is to try it both ways and test it under realistic-but-controlled conditions.
You're asking a question about performance, so clearly you care about performance. If you care about performance then the right thing to do is to set some performance goals and then write yourself a test suite which tracks your progress against those goals. Once you have a such a test suite you can then easily use it to test for yourself the truth or falsity of statements like "the debug build is slower".
And furthermore, you'll be able to get meaningful results. "Slower" is meaningless because it is not clear whether it's one microsecond slower or twenty minutes slower. "10% slower under realistic conditions" is more meaningful.
Spend the time you would have spent researching this question online on building a device which answers the question. You'll get far more accurate results that way. Anything you read online is just a guess about what might happen. Reason from facts you gathered yourself, not from other people's guesses about how your program might behave.
部分正确。在调试模式下,编译器为所有变量发出调试符号并按原样编译代码。在发布模式下,包括一些优化:
。由 JIT 决定。
完整的优化列表此处由埃里克·利珀特提供。
Partially true. In debug mode, the compiler emits debug symbols for all variables and compiles the code as is. In release mode, some optimizations are included:
The rest is up to the JIT.
Full list of optimizations here courtesy of Eric Lippert.