[Issue 9584] Exceptions in D are ludicrously slow (far worse than Java)

d-bugmail at puremagic.com d-bugmail at puremagic.com
Tue Dec 24 11:58:42 PST 2013


https://d.puremagic.com/issues/show_bug.cgi?id=9584



--- Comment #9 from hsteoh at quickfur.ath.cx 2013-12-24 11:58:33 PST ---
(In reply to comment #8)
> The situation is improved, now in my benchmarks D exceptions are about only
> 2-2.5 times slower than Java exceptions.
> 
> Further improvements in the GC or the optimizations linked here by Don (that I
> was not able to reproduce in the latest JavaVM) could bring the two even more
> on parity:
> http://www.javaspecialists.eu/archive/Issue187.html

According to that article, one of the main causes of slow exceptions is the
construction of the stack trace. I'm wondering, in D, if it's possible to
construct the stack trace *lazily*?

I.e., when we first create the Exception object, we do not immediately walk the
stack and generate trace entries for it; instead, we let the stack unwinder
incrementally create the trace as it unwinds the stack (since it's basically
walking up the stack anyway). When it reaches a catch block, of course, the
stack trace is still incomplete, since it has only been constructed up to that
point. But we still don't have to walk the rest of the stack at this point: we
can keep the partial stack trace in an incomplete state, and only if the catch
block tries to read the stack trace, then we will walk the rest of the stack to
create the entire trace. If the Exception gets rethrown, then we let the
unwinder continue to add more entries to the partial trace. If the Exception
gets ignored, then we discard the partial trace -- and we have saved the cost
of walking the rest of the stack.

Furthermore, we can keep the partial stack trace to a minimal representation,
e.g., as a list of function return addresses in binary, and only format it
nicely (lookup symbols, etc.) when the catch block actually asks for it. Then
this will also save on the cost of formatting the stack trace until it's
actually needed, or if the catch block just discards the Exception without ever
looking at the trace, then we've saved the cost of formatting it.

As for returning the same exception instance if the rate of throws is too high
(as described by the linked article): this may be more complicated to
implement, since you'll have to change the meaning of 'new' when applied to an
exception class. Currently in D, we first 'new' the Exception object (which may
be a derived class, so it's not trivial to check whether it's an instance of
Exception), then we throw it. I've written code before where the Exception
object is created by a separate function, and thrown elsewhere. It would
require rather major language changes to be able to return the same Exception
instance if the rate of throws is too high.

Whereas if we construct the stack trace lazily, we can save on the cost of
*all* Exceptions (most catch blocks don't bother reading the stack trace, for
example) with minimal/no language changes.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list