문제

They are telling us not to use exceptions to control flow of our programs because throwing exceptions is slow. I have never heard any explanation why is throwing exceptions so slow.

So the question is:

What is the mechanism of throwing exceptions and what are particular operations involved which may have performance impact?

EDIT:

Some clarification: I would like to hear what extra work is need by operation system to handle throwing exceptions. Is there some switching between user and kernel mode which are that costly? Or maybe constructing exception object is costly? Or maybe there is something with switching program flow what I am missing? My question is programming language agnostic (I hope so, but prove me wrong). However If you need some anchor then I am interest the most in .NET internals related with this topic.

EDIT2:

I don't have any issues with exceptions performance. I just would like to understand internals of this mechanism.

EDIT3:

Made my question more clear.

도움이 되었습니까?

해결책

Exception handling requires some complexity and "magic". Seconding @Joni's response a major cost is gathering the stack trace. When an exception is thrown, the run time has to walk down the stack's activation records looking for a compatible exception handler, executing finally blocks each step of the way. All this has to occur at run time; it can't be fixed up by the compiler. In languages like C++ destructors have to be executed.

Exception processing is essentially an out of band "exceptional" processing mode. Things that speed up normal execution such as caching don't work as well. (I would imagine locality-of-reference is a lot worse here). This processing could be optimized, but since exc handing is supposed to be "special" it's given less attention.

다른 팁

Exceptions are created in the application level; there is no operating system support for them. There is no particular reason why throwing and catching an exception should be slower than any other nonlocal transfer of control, like calling or returning from a function.

What makes exceptions "slower" than the alternative of returning error codes depends on the extra work required by the particulars of the programming environment. In Java for example the slowest part of throwing an exception is filling in the stack trace.

You have been misinformed, but the outcome on your actual code probably won't change either way. The exception handling system in .NET is actually quite fast, meaning its performance is comparable to you other options for error handling. However, like mentioned in another answer, you only want to use exceptions appropriately - i.e. only for exceptional situations which you do not expect to occur during a normal run of your application. The reasons for this are as follows:

  • Analyzing code flow involving exceptions is more complicated than code not involving exceptions, so your "normal" code should avoid throwing exceptions.
  • The Visual Studio debugger will report every time an exception is thrown. It's only one line in the output window, but if you are misusing exceptions then this wonderful feature will quickly turn into a nightmare.
  • Visual Studio has the ability to break when a particular type of exception is thrown. If you consistently use exceptions correctly (for their intended purpose, and only for indicating an actual exception of that type), this feature provides a way to quickly debug errors in your application related to error handling (recovery, reporting, etc.).

When it comes to handling actual exceptional situations, exception handling actually provides a performance benefit over other things like returning error codes. When it comes to branch prediction and hinting, the JIT can make the assumption that code will never throw an exception, allowing it to generate code that effectively uses any available branch prediction features of your processor to avoid branching overhead for code that includes error handling features but is not actively handling an error.

The main reason it's a bad idea to use exceptions for flow control is I should be able to attach a debugger and tell it to break on exceptions ... and it breaks in EXCEPTIONAL CASES. If the code is using exceptions for flow control and it breaks constantly under normal operation it becomes really hard to debug with out conditioning out exceptions etc... but then maybe you end up missing a real exceptional case.

If I write tests validating positive functionality, I should be able to run them with a debugger attached and it doesn't catch. If you can't do that, you might be abusing exceptions.

An example: let's say I have code to get an item by id. My code conclusively finds that an item by that id does not exist. Should I throw NotFoundException? This is a point of contention - I would say no - nothing exceptional/error happened here. Your code correctly found out nothing by that id existed and no errors finding that out occurred. these are cases where I see exceptions being abused and leads to exceptions getting thrown in non-excpetional cases.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top