1
12
除非在调试程序中运行,否则1900次迭代都不会花费一秒钟的时间。在调试器下运行性能测试是一个坏主意。 编辑:请注意,这不是更改为发布的情况 建造 -这是一个不使用调试器运行的情况;即,点击ctrl-f5而不是f5 . 尽管如此,当你可以很容易地避免它们时,挑起例外是 也 一个坏主意。 我对异常的性能的看法是:如果您恰当地使用它们,它们不应该导致重大的性能问题。 除非 无论如何,您正处于灾难性的情况下(例如,您尝试进行数十万次Web服务调用,但网络已关闭)。 在调试程序下,异常是昂贵的——当然在Visual Studio中是如此——因为要确定是否要闯入调试程序等,并且可能要做一些不必要的堆栈分析。他们仍然 有点 不管怎样都很贵,但你不应该把它们扔得太多而引起注意。还有堆栈展开、相关的捕获处理程序查找等工作要做,但这应该只在发生问题时发生。 编辑:当然,抛出异常仍然会使你每秒的迭代次数减少(尽管35000次仍然是一个非常低的数字-我希望超过100K),因为你几乎在做 没有什么 在非例外情况下。让我们看看这两个: 循环体的非异常版本
(正如评论中提到的,JIT很可能会优化这一点…) 异常版本:
你看到的表演越来越少了,这有什么奇怪的吗? 现在,将它与更常见的情况进行比较,在这种情况下,您要做大量的工作,可能是IO、对象创建等。 也许吧 引发异常。然后差异就变得不那么显著了。 |
2
2
退房 Chris Brumme's blog 特别注意 性能和趋势 有关异常为何变慢的解释。它们之所以被称为“例外”,是有原因的:它们不应该经常发生。 |
3
2
您可能还会发现这个常见问题很有帮助: How slow are .NET exceptions? |
4
2
这里还有另一个因素。如果在执行目录中有.pdb文件,那么当抛出异常时,.NET运行时将读取.pdb文件以获取要包含在异常堆栈跟踪中的代码行编号。这需要相当长的时间。尝试第一个方法(有异常的方法),在执行目录中包含或不包含.pdb文件。 我做了一个简单的计时测试,有或没有.pdb作为另一个问题的答案, here . |
5
1
编译器执行的一种优化,我认为这可能是“死代码消除”;还取决于您使用的编译器,后一个程序实际上正在执行汇编程序民间所说的“无操作”。 |
6
1
在我的测试中,“异常”代码没有那么慢——慢得多,但没有那么慢。 差异在于创建异常(或者,具体来说,是nullReferenceException)对象。其中最慢的部分是检索异常消息的字符串(有对getResourceString的内部调用)并获取堆栈跟踪。 |
7
0
这是一个糟糕的微观基准。 后一个“优化”循环具有编译时不变的特性,即测试始终为空,因此甚至不需要在尝试的赋值中进行编译。实际上,您正在测试一个空循环,每次都会引发一个异常。 一个真正好的JIT甚至可以完全删除循环,注意循环没有主体,因此除了增加计数器之外没有副作用,计数器本身也没有使用(这是不太可能的,因为这样的优化在现实世界中几乎没有实用性)。 抛出异常相当昂贵(相对于传统的分支控制流)[1]主要是由于以下三个原因:
不管怎样,在一个紧密的循环中抛出和捕获异常几乎肯定是一个有很大缺陷的设计,但是如果您试图测量这种影响,那么您应该编写一个实际做到这一点的循环。
|
M.Jane · 组织和编写异常类的正确方法 6 年前 |
shubham daharwal · java中的内部捕获异常 6 年前 |
Jon · 如何在不需要任何操作的情况下处理Python异常 6 年前 |
felix1415 · C++捕获(标准::异常和e)与捕获(…) 6 年前 |
k0pernikus · 如何在scala中键入可能引发异常的函数? 6 年前 |