Contracts or Exceptions?
Jonathan M Davis
jmdavisProg at gmx.com
Wed Mar 30 14:47:28 PDT 2011
On 2011-03-30 14:05, Ali Çehreli wrote:
> On 03/30/2011 12:40 PM, Jonathan M Davis wrote:
> > 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
>
> That's too much. :) I get consistent results with -O on a 64-bit Ubuntu:
>
> -1 μs and -9 hnsecs
> -832 μs and -9 hnsecs
>
> But with the addition of the -m64 flag, it's more than 4 times faster:
>
> -1 μs
> -175 μs and -4 hnsecs
>
> Still not good. :-/
LOL. And I just realized that I did those subtractions backwards. They're
negative where they should be positive. Oh well. The numbers are still clear,
and I was in a hurry when I wrote the test code.
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list