On exceptions in D

Dmitry Olshansky dmitry.olsh at gmail.com
Mon Feb 10 02:08:40 PST 2014


10-Feb-2014 05:16, Jonathan M Davis пишет:
> On Sunday, February 09, 2014 21:57:13 Dmitry Olshansky wrote:
>> Split out of "List of Phobos functions that allocate memory?".
>>
>> To reiterate, here is some critique, compiled:
>>
>> 1. Exceptions are class instances, hence (by default) are allocated on
>> GC heap. This is wrong default, GC is no place for temporaries.
>


> The place where this becomes an issue then is code that needs exceptions to be
> really fast (e.g. it sounds like vibe.d falls in that camp). And in that case,
> it doesn't really matter whether the exceptions are allocated on the GC heap
> or malloc's heap. If memory allocation is slowing them down, then they need to
> get rid of the memory allocation entirely, in which case, doing something like
> having a pool of pre-allocated exception objects to reuse would make a lot
> more sense.

Yes, but this is more of reuse of  the memory and allocating it cheaply. 
Pools are especially good for objects with short lifetime.

> And in that case, it would probably be better if they weren't on
> the GC heap, but the exception-throwing code wouldn't really care either way.
> That would be up to the pool. The same goes if only a single, static exception
> were used. It might be marginally better if it weren't on the GC heap, because
> it would avoid being scanned, but in those cases where you want speed, you
> _want_ long lifetimes for the exceptions, not short lifetimes like you're
> suggesting, because you want to reuse the exceptions in order to avoid needing
> to allocate new ones.

Exceptions have short lifetimes, that's a simple fact that can be 
inferred poking at code bases. Their lifespan in most cases is from 
throw statement to the next catch.
Now if memory is preallocated or not has no bearing to lifetime, as each 
time an exception is thrown with different data means this is a "new" 
exception regardless of what memory is being reused.

> The only way that short lifetimes would work is if we
> weren't dealing with classes and the exceptions were on the stack, but that
> negates our ability to have an exception hierarchy - which is critical to how
> exceptions work.

I see you imply that class hierarchy and polymorphism is achieved only 
with classes. This is a good point. I wonder if virtual functions 
mechanism can be generalized beyond classes.

>
> And if some code is getting exceptions frequently enough that the memory
> allocation is the bottleneck, then maybe exceptions aren't the best choice
> either.

If the allocation is the bottleneck - cure the allocator.

> I agree that exceptions need to be much, much faster than they are,
> but they're still intended for the error case, which should be relatively
> infrequent.

Exceptions are a mechanism of error handling that has an advantage of 
cleanly propagating information up across stack frames to the actual 
point where it could be deal with. Yes, stack unwind implies that it 
shouldn't probably be 99% of cases.

>> 3. Turns out message is expected to be a string, formatted apriori:
>> https://github.com/D-Programming-Language/druntime/blob/master/src/object_.d
>> #L1306 Formatting a string in such setting inevitably allocates and it
>> happens at the throw site, even if nobody is using that message down the
>> line. At least one can override toString...
>
> Ideally, creating the string that toString returns would be put off until
> toString is called (particularly since that includes the stack trace), but I
> would hope that creating the message string to pass to the exception's
> constructor would be cheap enough (particularly in light of the fact that the
> exception is heap-allocated anyway)

Here it goes - bah if we allocate why not allocate twice. I'm out of 
words on this point.


-- 
Dmitry Olshansky


More information about the Digitalmars-d mailing list