5 ms·
From what I understand this about how the performance of code that throws scales with the number of cores. What is the state of current compilers for the non-t
by weinzierl 2y ago
From what I understand this about how the performance of code that throws scales with the number of cores.
What is the state of current compilers for the non-throwing case? If I have code with exceptions, but test a case that does not actually throw? Will it be as fast as the same code but with exceptions removed altogether?
EDIT: I just saw that Justine's (jart) comment answers this.
- adzm 2y agoHaving exceptions as a possibility requires at least some bookkeeping and prevents certain kinds of optimizations due to the compiler not being able to know where an exception could come from. Generally however this is not that much of an issue, and only worth dealing with in the rarest of cases.
- weinzierl 2y agoThat makes sense. I wonder how the amount for this bookkeeping stacks up against the overhead of returning a sum type composed of error and result (like Rust Result<T, E>)? Always returning a slightly "fatter" type must certainly have an associated cost as well and it is to pay in any case - error or not.
- gpderetta 2y agoAt the limit, you can make Result<T,E> very cheap: with a specifically designed ABI you just need a bit in the flags register and a single (predictable) conditional jump on the return path (see for example the Herbceptions papers). At the limit limit, there is no difference between Result<T,E> and checked exceptions, with enough syntactic sugar they can be equivalent both semantically and syntactically [1]. [1] One advantage of typical C++ exceptions implementations, is that if the exception is not caught the stack is not unwound and the stack trace is preserved in the core file. In principle the same thing could be done for Result.
- bluGill 2y agoWith an exception (not checked exceptions) you get the advantage of the compiler knows about this and can optimize some code paths - any function that doesn't handle the function or have clean up to do can be bypassed, while result/checked exceptions need to go into that function anyway - which may be faster, more benchmarks needed. (though is possible a "sufficiently smart" compiler could understand thus pattern and turn it into an exception). So the real question is syntax - which do you prefer: having to write some result type all over instead of the regular return type you mean, or knowing that "magically" at unpredictable times your function will just abort in the middle. There are pros and cons to both, so anyone arguing absolutely for either side is wrong - at least now when we don't have decades of experience with result in large projects (though maybe we do in a single project)
- gpderetta 2y ago> With an exception (not checked exceptions) you get the advantage of the compiler knows about this and can optimize some code paths while result/checked exceptions need to go into that function anyway. Once you convert them in CPS form there is really no difference between the two. In principle you could compile both to exactly the same code. [edit: also not sure why are you singling out checked exceptions] [edit: specifically you could compile any code that returns an Either to a function that takes two return continuations instead of just one, and in CPS form exception-like non-local exits are trivial] Of course in practice traditional procedural languages do not compile through CPS and use abnormal edges in basic blocks to represent exceptions. > There are pros and cons to both, so anyone arguing absolutely for either side is wrong I'm in the camp that, in a well designed language[1], there would be no difference between the two :D [1] according to my personal preferences that I can assure you are completely objective!
- kllrnohj 2y ago> At the limit limit, there is no difference between Result<T,E> and checked exceptions How do you figure? A Result<T,E> always means a branch after function calls, while checked exceptions have no such cost. Toy example: https://godbolt.org/z/Gqo9n17c6 https://godbolt.org/z/Gqo9n17c6 It's trivially observed that exceptions simply have less code in the normal path. There's no post-call checking for errors, which is of course present in the Result<T,E> approach. And even where the exception is caught, that's not part of the "hot loop". It's not executed at all normally. Unwinding exceptions are completely free when they don't happen. The same is simply not true and never can be true of a return-value based propagation.
- kllrnohj 2y agoWhat optimizations are disabled? I don't see any reason any of them would be, nor is there any bookkeeping. The stack itself is the bookkeeping which is required regardless. The exception-specific stuff is stored elsewhere, which is why throwing an exception is expensive, but if it doesn't throw then nothing in the hot path was pessimised.