5 ms·
In Java/C# land exceptions are EXPENSIVE. Like magnatudes more expensive. You have to build a full stack trace etc. Removing places in the code where it is "Thr
by kenoyer130 7y ago
In Java/C# land exceptions are EXPENSIVE. Like magnatudes more expensive. You have to build a full stack trace etc. Removing places in the code where it is "Throwing exceptions for non exceptional circumstances" has a dramatic performance increase benefit.
- iainmerrick 7y agoC++ too. I suspect it’s true in almost every language. Maybe not Python? But Python is slow regardless.
- petters 7y agoIn C++, exceptions are often faster than manual error checking when errors are rare. But C++ does not provide a stack trace.
- safety-second 7y agoC++ exceptions are only good if you use them like signals from C or panics in Go. This means you have to use error values for 99% of errors or you lose this benefit. The fact that the STL sprinkles exceptions everywhere doesn't help this. C++ exceptions are so non-deterministic and slow that every real-time system disables them just to be sure.
- iainmerrick 7y agoYou don’t always get a stack trace, but it still has to unwind the stack, calling destructors as needed, and check the exception’s type against each catch block.
- earenndil 7y agoHence 'when errors are rare'.
- iainmerrick 7y agoI guess we’re violently agreeing? Exceptions are an order of magnitude (or several orders) slower than function calls and returns; but that can still be efficient overall, if only a tiny fraction of calls fail. I’d simply add that most people greatly underestimate how expensive exceptions are, even in C++.
- AstralStorm 7y agoCalling the destructors is identical to ending any scope in C++, including function calls. Where is that extra expense?
- iainmerrick 7y agoYou likely have to parse exception blocks and maybe chase pointers to find the objects to destroy. In the happy path, you can just call the destructors directly.
- renox 7y ago> But C++ does not provide a stack trace Which makes exception in C++ a very, very bad idea! My reaction to 'the test fails because map::at threw an exception': stupid STL!! A core dump would be so much easier to analyze.. Gdb's 'catch thow' is wonderful (well, it is after I fixed the part of our codebase which use exceptions as a control flow mechanism)
- nemetroid 7y ago> My reaction to 'the test fails because map::at threw an exception': stupid STL!! > A core dump would be so much easier to analyze.. Uncaught exceptions call terminate(), which by default calls abort(), which generates a core dump. So if you want a core dump, just avoid catching the exception.
- renox 7y agoExcept that I didn't put all these "catch".. But you're right, that's what should be done (or at least, rethrowing the exception from the catch block).
- AstralStorm 7y agoC++ can have a stack trace, there are enough libraries providing this functionality and even compiler extensions. Say, libunwind, though you will have to demangle names. And a debugger will see the stack as it is. Also works in C.
- aratauto 7y agoTechnically in Java it is possible to create an exception object once, and throw it multiple times, making throws much cheaper as the stack trace is filled during the object's construction only.
- acidictadpole 7y agoDoes this actually save much time? I thought it was the throw mechanic that was slow, rather than just creating the exception?
- aratauto 7y agoAccording my unscientific tests, it is about over 100 times faster. On my laptop I can throw one million exceptions in 15ms millisecond, when reusing the same exception objects, compared to 2 seconds when creating a new exception object every time with a quite shallow stack. When a new exception object is created, the slowest operation is filling information about the stack trace. It is possible to override Exception's fillInStackTrace() with an empty implementation. In this case throwing exceptions with new exception objects, is only slightly slower than using one exception object (17ms vs 15ms for 1M throws). Deeper stacks make difference even bigger. Adding 100 nested invocations to the stack slow downs the classic approach (a new exception object created just before invocation) to 9 seconds, while alternative approaches are not affected.
- haagen 7y agohttp://normanmaurer.me/blog/2013/11/09/The-hidden-performance-costs-of-instantiating-Throwables/ http://normanmaurer.me/blog/2013/11/09/The-hidden-performanc...
- ReidZB 7y agoThe HotSpot JVM may decide to stop building stack traces in some circumstances to improve performance (see the 'OmitStackTraceInFastThrow' option, enabled by default). Not sure about other languages / runtimes though. That said, I agree exceptions should be reserved for exceptional circumstances. Something like checking if a record exists or not should probably use something like Optional instead, unless you are in a situation where a record "should" exist but doesn't (which is itself an exceptional case).