Live data from Hacker News

Avoid exception throwing in performance-sensitive code

lemire.me

11–20 of 243 posts

Re: Avoid exception throwing in performance-sensitive code

#11

I'm completely ignorant of the subject, but most surprising to me in his example was that the compiler didn't optimize away the inefficiency. Is there something about exception handling that makes it not get taken into account during optimization?

C++ exceptions and by extension Rust panics and C# exceptions (with caveats) involve stack unwinding as well as gathering of corresponding details and producing an exception object (C#). It is very expensive and using it as a normal condition in general is not the best idea. It is by definition cannot be optimized in a way that gets both good performance and keeps all existing side effects.

That's why Rust's Result is vastly superior because it out of box pushes the users to very efficient and idiomatic error handling mechanism which is based on its enum types that enjoy a lot of compiler optimizations.

You can also achieve fairly good results with struct-based custom Result implementations in C# but until the language gets the support of proper discriminated unions, it will always be inferior.

Thankfully, in C# and, I assume, in other exception-based languages the compiler is smart enough to recognize exceptions as cold paths and correctly reorder emitted code to minimize their impact when you do not throw them. But traversing try-catch blocks still tends to pessimize the codegen significantly hence heavy reliance of C# on various throw helpers to keep hot paths clean.

Re: Avoid exception throwing in performance-sensitive code

#12
post #8

Different 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…

Great details! Why only half the time though? What is the behavior the rest of the time?

I wanted to make sure all code paths were executed, and so I filled the array of ints with 50% negative values.

Re: Avoid exception throwing in performance-sensitive code

#13

Exceptions are great for exceptional conditions in performance-sensitive code. They provide a mechanism to move your error-handling code far out of the hot path. If you are expecting an occasional exception, they are terrible, and the C way of returning an error code is the way to go. In most cases, when you don't control what you expect, exceptions are not great. In a constrained embedded system or a trading system,…

Why would error-handling code impact performance?

Besides, exceptions in C++ are known to have negative impacts on overall performance even if you don't use them. (see: https://preshing.com/20110807/the-cost-of-enabling-exception...)

Re: Avoid exception throwing in performance-sensitive code

#14
This should be, avoid exception catching in performance sensitive code. Assuming one isn’t doing exceptions instead of normal flow control like if/else, the dominant cost is the branch(es) to determine if there is an error to communicate. Not that there is a possible exception. Now, the catching part/after it is throw sure that is expensive in at least C++. The full stack needs to be unwound along with potential RTTI. So this becomes, do you really need that branch in the hot loop kind of problem

Re: Avoid exception throwing in performance-sensitive code

#15

I'm completely ignorant of the subject, but most surprising to me in his example was that the compiler didn't optimize away the inefficiency. Is there something about exception handling that makes it not get taken into account during optimization?

I'm no C++ expert but I think it must be hard for the compiler to figure out - the noexcept keyword exists in C++ to denote a method that doesn't throw exceptions (so the compiler knows it doesn't need to add default exception handling code). Given that this is a manual thing up to the programmer it mustn't be straight forward for the compiler to infer.

noexcept actually forces it, if it doesn’t know it must essentially wrap the function body in a try { …body… } catch(…) { terminate( ); }. So the compiler is doing the same amount of work inside the function. Outside it can assume that no exception will escape that function, yes. If it knows, it doesn’t need to.

Re: Avoid exception throwing in performance-sensitive code

#16
This post is poorly named. What it's saying is to avoid throwing exceptions for normal flow control, and just use them for exceptional cases (file not found, etc).

Performance-sensitive code or not, exceptions for exceptional situations are not going to hinder the app's performance until the exceptional situation becomes common (unless your language does lots of exception setup work on the happy path - which most have stopped doing by now).

Re: Avoid exception throwing in performance-sensitive code

#17
post #13

Exceptions are great for exceptional conditions in performance-sensitive code. They provide a mechanism to move your error-handling code far out of the hot path. If you are expecting an occasional exception, they are terrible, and the C way of returning an error code is the way to go. In most cases, when you don't control what you expect, exceptions are not great. In a constrained embedded system or a trading system,…

Why would error-handling code impact performance? Besides, exceptions in C++ are known to have negative impacts on overall performance even if you don't use them. (see: https://preshing.com/20110807/the-cost-of-enabling-exception... )

This blog post is specifically talking about 32-bit x86 C++ ABI, which was notoriously not zero-cost wrt exceptions even on success-only code paths. Lessons learned from that went into the Itanium C++ exceptions ABI based on static unwind maps, which has been adopted by basically every other architecture except for Windows, which has its own take (that is still zero-cost).

Re: Avoid exception throwing in performance-sensitive code

#18

I'm completely ignorant of the subject, but most surprising to me in his example was that the compiler didn't optimize away the inefficiency. Is there something about exception handling that makes it not get taken into account during optimization?

C++ exceptions have a lot of machinery behind the scenes, and I don’t think anybody has ever really put the effort in to optimize pathological edge cases like this.

A lot of time and effort went into optimizing the most common case (no exceptions - ideally this should be no-cost) at the expense of everything else. It's very much by design.

Re: Avoid exception throwing in performance-sensitive code

#20

TIL that it's even possible to use exceptions instead of bog standard if statements. Would love to know why people would do this, though. Surely everyone masters if-else ssatements well before they even learn what a try-catch statement is!?

If .. Else .. Finally?
Post reply on HN