This is one of my basic interview questions to candidates and it is amazing how many people have no idea how exceptions work or how much they cost. Back in 2005, I was involved in a replatforming of the legacy COBOL and TRANSACT HP3000 mainframe codebase to the modern system. The code was transpiled into an [unholy mess of] C# and ASP.NET. The Transact code was extremely procedural and had mainframe forms interspread…
That seems exceptionally bad!
Avoid exception throwing in performance-sensitive code
191–200 of 243 posts
Re: Avoid exception throwing in performance-sensitive code
#192Different languages have different exception handing optimizations. A Java version of the example can run very slow or very fast, depending on how clever you are. When a new RuntimeException is thrown half the time, the example runs about 650 times slower when compared to a function which adds up the integers without using exceptions. If I define an exception subclass which doesn't fill in the stack trace, then it ru…
Moreover, different languages implement the exception handling differently. The article focuses on C++, which has a notion of object destructors (most – but not all – programming languages don't have the destructors). Implications for the exception handling are manyfold: upon an entry into a «try» block, a C++ compiler has to account for all objects created at the method (or function) scope up until this point and re…
Re: Avoid exception throwing in performance-sensitive code
#193Earlier quoted context omitted.
I think what Java got wrong was allowing catching unchecked exceptions. If Java had only allowed recovering from checked exceptions, it would have been a very similar experience to Rust's Result and panic. Instead, the trend was to avoid using checked exceptions at all, which perpetuated the crazy situation we're in where library code can suddenly abort and the author shrugs and says "shoulda read the docs".
Java got wrong with the concept of checked exceptions. They're not needed. Python, C++ or JavaScript exceptions are totally fine. And checked exceptions bring nothing but issues. The only thing that I'd add to the unchecked exceptions is noexcept with compile-time checking. Something along the lines: 1. You can declare method as `nothrows`. Compiler will ensure that no exceptions are thrown (`java.lang.Error` can sti…
And even though C++ dropped exception specifications, they still kept the difference between might throw anything or doesn't throw at all, and there is also the paper to reintroduce them Swift style.
Re: Avoid exception throwing in performance-sensitive code
#194Earlier quoted context omitted.
Stack traces. The information required to build a stack trace is deliberately kept off the critical path so it doesn't impact performance during normal operation, but that means that building a stack trace requires going out and fetching the debug symbols and correlating them. Without stack traces, exceptions are just a type of goto.
While you are absolutely right that collecting stack traces is an extremely costly operation, it's not the only problem. For example, in C++, which doesn't collect any kind of stack trace, throwing an exception is still ~1 order of magnitude slower than returning a value through all the layers. Note that this cost only happens when the exception is thrown; exception-based code is otherwise slightly faster than `if re…
Re: Avoid exception throwing in performance-sensitive code
#195Earlier quoted context omitted.
My point is that this is in no way different from any other class of errors, _except_ in those cases where it is. It's practical to assume all errors are handled like this, because this catch all needs to exist anyway. And unless you have _very specific needs_, this can be automated.
I think conflating these two into one paradigm is worse. The catch-all (exceptions) style is nice only for a few very specific cases, like the request handler example. Everywhere else I want to either bubble up (like exceptions, but Result and ? sugar is as good or better), OR I want to handle the error. For the latter case, exceptions are not good at all.
Re: Avoid exception throwing in performance-sensitive code
#196Earlier quoted context omitted.
I think what Java got wrong was allowing catching unchecked exceptions. If Java had only allowed recovering from checked exceptions, it would have been a very similar experience to Rust's Result and panic. Instead, the trend was to avoid using checked exceptions at all, which perpetuated the crazy situation we're in where library code can suddenly abort and the author shrugs and says "shoulda read the docs".
Java got wrong with the concept of checked exceptions. They're not needed. Python, C++ or JavaScript exceptions are totally fine. And checked exceptions bring nothing but issues. The only thing that I'd add to the unchecked exceptions is noexcept with compile-time checking. Something along the lines: 1. You can declare method as `nothrows`. Compiler will ensure that no exceptions are thrown (`java.lang.Error` can sti…
Recoverable error states are part of your function's interface. Languages with exceptions make this implicit: in order to know how to interface with a function's error states you have to go digging through the docs, which hopefully document the exceptions it throws. If they don't, then you either have to trace the entire call tree or just wait for the library to throw something so you know what you're supposed to be catching.
On the other hand, if a language requires that recoverable errors be documented in the function signature (either as a checked exception or error-as-value), you know that you're either handling the exceptions or intentionally letting them propagate. There are no surprises at runtime because the set of all possible error states is known statically.
Re: Avoid exception throwing in performance-sensitive code
#197Earlier quoted context omitted.
I think what Java got wrong was allowing catching unchecked exceptions. If Java had only allowed recovering from checked exceptions, it would have been a very similar experience to Rust's Result and panic. Instead, the trend was to avoid using checked exceptions at all, which perpetuated the crazy situation we're in where library code can suddenly abort and the author shrugs and says "shoulda read the docs".
> where library code can suddenly abort and the author shrugs and says "shoulda read the docs". In see no difference. Except for the fact that you don't have the stacktrace (in Go), and unroll the Stack manually. In any case, there'll be a generic catch (whatever you call it) on the top level of your daemon to recover from the failed request and handle the next.
As for stack traces: checked exceptions are semantically almost identical to error-as-value but they do give you a stack trace. They give you all the static guarantees of error-as-value plus the benefit of being able to know where the error came from.
Re: Avoid exception throwing in performance-sensitive code
#198Earlier quoted context omitted.
I think what Java got wrong was allowing catching unchecked exceptions. If Java had only allowed recovering from checked exceptions, it would have been a very similar experience to Rust's Result and panic. Instead, the trend was to avoid using checked exceptions at all, which perpetuated the crazy situation we're in where library code can suddenly abort and the author shrugs and says "shoulda read the docs".
> I think what Java got wrong was allowing catching unchecked exceptions. If Java had only allowed recovering from checked exceptions, it would have been a very similar experience to Rust's Result and panic. > Instead, the trend was to avoid using checked exceptions at all Java's type system was far too weak for that to be at all practical. Early Java not only didn't have first-class functions, it didn't even have ge…
My point is less that Java could have done this differently with the other type choices that they made and more that it's a shame that Java's implementation of checked exceptions has poisoned the concept for so many. I think a language with strong type inference and a checked exception mechanism would be better than Rust's Result type because you get the stack trace.
Re: Avoid exception throwing in performance-sensitive code
#199Different languages have different exception handing optimizations. A Java version of the example can run very slow or very fast, depending on how clever you are. When a new RuntimeException is thrown half the time, the example runs about 650 times slower when compared to a function which adds up the integers without using exceptions. If I define an exception subclass which doesn't fill in the stack trace, then it ru…
I know the article is about performance but from a sheer programmjng perspective brqnches are there for a reason.
Re: Avoid exception throwing in performance-sensitive code
#200Earlier quoted context omitted.
Stack traces. The information required to build a stack trace is deliberately kept off the critical path so it doesn't impact performance during normal operation, but that means that building a stack trace requires going out and fetching the debug symbols and correlating them. Without stack traces, exceptions are just a type of goto.
What about dynamic languages? Are they always collecting the stack and keeping it into some exception object that the exception can grab the data from at any time? And if that's the case wouldn't it always be slow regardless of raising or not ?