Contracts or Exceptions?

Jonathan M Davis jmdavisProg at gmx.com
Wed Mar 30 12:40:48 PDT 2011


On 2011-03-30 05:09, spir wrote:
> On 03/30/2011 05:32 AM, Ali Çehreli wrote:
> > On 03/29/2011 03:40 PM, Kai Meyer wrote:
> >>  I was given two words of advice on exceptions:
> >>  "Use exceptions for the exceptional"
> >>  "Use exceptions only for the exceptional"
> > 
> > Those advices are given by wise people: they are wise only because they
> > leave the definition as vague as "exceptional." :)
> > 
> > And what do we do for the "not so exceptional"? Do we return error codes?
> > So the function implementation will be complicated and the caller code
> > will be complicated.
> > 
> > Exceptions are a great tool to eliminate the need for error codes.
> > 
> > Here is what I follow:
> > 
> > - Functions have specific tasks to do; if those tasks cannot be
> > accomplished, the function must throw.
> > 
> > In some cases the function can continue, but that behavior must be
> > documented. For example, if an HTML library function is responsible for
> > making HTML headers, of which only the levels in the range of 1-6 are
> > valid, that function may throw when the level is outside of the valid
> > range, for in that case it cannot "make an HTML header"; or it can
> > document that if the level is outside of the range, 1 or 6 will be used.
> > 
> > - Catch exceptions only when there is a sensible thing to do at that
> > level: log an error, skip that operation, go back to the user with an
> > error code, take corrective action, etc.
> > 
> > Disclaimer: That is what I follow in C++ code. I don't have experience
> > with exception safety in D. I don't know issues that may be specific to
> > D.
> 
> These are sensible and well expressed guidelines, thank you.
> In other languages, I happened to use exceptions as a // channel for
> side-information (eg 'nomatch' for a matching func), but in D I realised
> how 'exceptionnally' (!) costly throwing & catching exceptions is, so that
> I do not do it anymore. No idea though whether this exceptional cost is
> perticular to D.

I'd have to measure it in C++, Java, and C#, but I'm pretty sure that D's is 
at least a lot slower than Java. Java uses exceptions all over the place, and 
it works quite well overall IMHO, but I never got the impression that there 
was any kind of major overhead for exceptions (though obviously there's going 
to be at least _some_ performance hit for derailing the thread of execution 
like that). In D however, it seems to be significant. As I've been reworking 
std.datetime's unit tests, I've found that I've had to be very careful about 
how often I use assertThrown, or there is a _major_ increase in how long the 
unit tests take to execute. While changing some tests, I had some loops which 
included assertThrown. It turns out that with assertThrown, they'd be 10+ 
seconds long, whereas without, they'd be a matter of milliseconds. So, the 
performance of exceptions in D is quite poor and while it probably doesn't 
matter all that much for normal code execution, it's definitely annoying for 
heavy unit testing which is validating that functions throw when they're 
supposed to throw.

As a test, on my machine, this program

===
import std.datetime;
import std.exception;
import std.stdio;

void main()
{
    auto date = Date(2011, 5, 7);
    {
        auto curr = Clock.currTime();
        assertNotThown!DateTimeException(date.day = 29);
        writeln(curr - Clock.currTime());
    }

    {
        auto curr = Clock.currTime();
        assertThrown!DateTimeException(date.day = 32);
        writeln(curr - Clock.currTime());
    }
}
===

prints out this

-1 μs and -4 hnsecs
-637 μs and -7 hnsecs

Naturally, the executation time does vary some, but it's consistently over 400 
times (and generally more like 450 times) more expensive to have the exception 
be thrown and caught than it is to have it not be thrown. That's _really_ 
expensive. I'd be stunned if Java's or C#'s were that bad, but I'd have to go 
and test it. C++'s might be, but given how much Java and C# use exceptions, it 
would ludicrous if either of them had that kind of overhead for exceptions.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list