Subject: Re: [boost] Boost.Outcome review - First questions
From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2017-05-24 13:29:12
2017-05-24 15:01 GMT+02:00 Hartmut Kaiser via Boost <boost_at_[hidden]>:
> > > 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
> > 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.
> Emil, thanks for asking this question.
> > 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.
> Ok, so let's assume you have on average 10 stack frames, that brings us to
> not more than a few microseconds for handling a thrown exception.
> Now, how often do you throw exceptions (if used properly - for exceptional
> cases - that is)? In real world applications I'd assume that you don't
> more than (at the very max) a handful every second (and I'm sure this is
> already stretching it) - but please correct me if I'm wrong (I often am).
> Even this extreme case would cause less than a 1/10th of a percent of
> 'overhead' caused by throwing exceptions.
> IOW, you will not be able to measure the overhead introduced by throwing
> exceptions in real world code.
> > > Practically speaking exception handling overhead occurs only at
> > > 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.
> Could you clarify this please? Are you saying that using exceptions without
> throwing them doesn't cause any overhead nowadays anymore?
> > > 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.
> Again, please clarify. Does this mean that even if you throw exceptions
> (using MSVC) the overhead isn't too bad in the first place?
> > > 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
> > > 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.
> I'm not sure I understand what you mean by 'for much improved almost
> Could you summarize your ACCU talk in two sentences for me, please?
> So, Emil's initial question is still unanswered (at least for me, and
> feel free to just point me to an email thread or similar which already
> succinctly answers this - I apologize if I missed that): what is the use
> case for the outcome library?
> Replacing exceptions for error handling? If yes, why?
> Replacing the use of error codes for error handling? If yes, why not using
> I'd appreciate any possible clarification on this matter as I'm growing
> and more confused by the ongoing discussions.
Maybe I can answer this. The most general answer is that Boost.Outcome is
for people who want to reasonably decently report and handle failures and
at the same time choose, or are forced, not to use exceptions.
The reasons for not using exceptions may be different:
- Real or imaginary concerns about performance
- A personal style of programming
- Company's policy to compile with exceptions disabled
- Maintaining a code base that was never designed with exception-safety
- Making all control paths explicit, as opposed to having hidden control
paths caused exceptions potentially thrown from any place
- Parts of the programs/frameworks that themselves implement exception
handling and cannot afford to use exceptions, like propagating failure
reports across threads, tasks, fibers...
Once you have decided not to use exceptions in some part of the program,
Boost.Outcome offers convenient abstractions for you, likely superior to
error codes. It implements 95% the currently being standardized
`std::expected` library, plus a number of other useful additions.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk