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.
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).
Maybe not Python? But Python is slow regardless.
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)
> 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.
Also works in C.
I’d simply add that most people greatly underestimate how expensive exceptions are, even in C++.