Boost logo

Boost :

Subject: Re: [boost] Boost.Outcome review - First questions
From: Emil Dotchevski (emildotchevski_at_[hidden])
Date: 2017-05-24 18:54:17


On Tue, May 23, 2017 at 6:38 PM, Niall Douglas via Boost <
boost_at_[hidden]> wrote:

> > I keep seeing the assertion that C++ exceptions create performance
> problems
> > but I am yet to see actual data to support it. Not a simple toy case but
> an
> > actual program that was shown to be slow when using exceptions, that
> issue
> > couldn't be fixed otherwise and the solution was to not use exceptions.
>
> As I already said, throwing and catching C++ exceptions on a table based
> EH implementation is very slow, and moreover, unpredictably so. It costs
> approx 1500-3000 CPU cycles per stack frame unwound. In this situation,
> using integer error codes, or error_code, or Outcome instead delivers
> huge improvements.
>

I don't dispute that exception handling has overhead and that you can
construct a toy example that shows that. However, people who choose to
avoid exceptions make a bigger claim, something along the lines of "in my
domain we can't afford exception handling overhead". I have _never_ seen
hard data to support this.

Moreover, in the above response you seem to be talking about the speed of
the unwinding itself, not about the effect of exception handling on the
general speed of the code (when exceptions are not thrown). This may be
true but your reasoning is still rather abstract. Does anyone have a
concrete program where reporting a failure by throwing would be too
expensive? If not, what problem are we aiming to solve with Outcome?

By the way, it would be very helpful if the examples in Outcome don't talk
about failures to open files, especially if the objection to using
exceptions is that their performance is "unpredictable".

> > Practically speaking exception handling overhead occurs only at function
> > entry and exit.
>
> Only the case on non-table based EH implementations such as MSVC x86.
> Anything newer has zero, absolutely *zero* runtime overhead except for
> code bloat effect on cache exhaustion.
>

Sure, I'm taking the worst case scenario. My claim is that 1) the speed
overhead of exception handling is usually negligible even in that case and
2) when it is not it can be removed by inlining the function.

> > It disappears in thin air (all of it) by simply inlining
> > the function, which would be done in performance-critical parts of the
> code
> > anyway (and MSVC, whose exception handling overhead is probably the
> worst,
> > can inline functions even at link time.)
>
> Actually MSVC's exception handling performance with table based EH is by
> far the best of any of the major compilers. It's twice as fast as GCC
> for example. The next best is Apple XCode, and far behind is POSIX clang
> and GCC.
>

I agree that talking about actual compilers today is relevant and should be
considered, so when I'm discussing exception handling overhead I do mean
actual real world uses.

That said, in the spirit of C++ we should think of exception handling
abstractly, even not considering specific ABIs. After all, we don't talk
about the overhead of using for loops vs. do-while, do we? It should be the
same with exceptions. If I have:

try { throw x(); } catch( x & ) { }

there is no reason for any exception to be actually thrown. In principle,
compilers should be able to see that the above is noop.

>From this point of view, there should be no performance difference between
returning an error code or throwing an exception, and if there is, that is
a problem of the compiler or the ABI but not of the semantics of exception
handling as defined by C++.

We shouldn't be inventing new styles of reporting failures to work around
the shortcomings of C++ code generators, or at least we should openly state
this as the main motivation.

> > So I must ask: what is the practical problem solved by not using
> exceptions
> > in general and Outcome in particular? It seems to me this is driven by a
> > design preference for one coding style over another, which is fine, but
> > nobody seems to be having that discussion. The cost of not using
> exceptions
> > is that we're throwing away the ability to enforce postconditions. What's
> > the upside?
>
> If you are using integer return codes, the claim is that you should be
> using Expected/Outcome instead for much improved almost everything. My
> ACCU talk video covers this in depth.
>

What I'm saying is that you shouldn't be using integer or any other error
codes except to prevent C++ exceptions from crossing a language barrier.

Emil


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk