Improve Appender growth scheme.

This commit is contained in:
monarch dodra 2013-07-12 18:10:39 +02:00 committed by monarchdodra
parent 395b72204e
commit 0b8302b68d

View file

@ -2234,14 +2234,19 @@ struct Appender(A : T[], T)
// ensure we can add nelems elements, resizing as necessary
private void ensureAddable(size_t nelems) @safe pure nothrow
{
static size_t newCapacity(size_t newlength) @safe pure nothrow
//Calculates an efficient growth scheme based on the old capacity
//of data, and the minimum requested capacity.
//arg curLen: The current length
//arg reqLen: The length as requested by the user
//ret sugLen: A suggested growth.
static size_t newCapacity(size_t curLen, size_t reqLen) @safe pure nothrow
{
long mult = 100 + (1000L) / (bsr(newlength * T.sizeof) + 1);
long mult = 100 + (1000L) / (bsr(curLen * T.sizeof) + 1);
// limit to doubling the length, we don't want to grow too much
if(mult > 200)
mult = 200;
auto newext = cast(size_t)((newlength * mult + 99) / 100);
return newext > newlength ? newext : newlength;
auto sugLen = cast(size_t)((curLen * mult + 99) / 100);
return max(reqLen, sugLen);
}
if (!_data)
@ -2274,7 +2279,7 @@ struct Appender(A : T[], T)
// Time to reallocate.
// We need to almost duplicate what's in druntime, except we
// have better access to the capacity field.
auto newlen = newCapacity(reqlen);
auto newlen = newCapacity(_data.capacity, reqlen);
// first, try extending the current block
auto u = ()@trusted{ return
GC.extend(_data.arr.ptr, nelems * T.sizeof, (newlen - len) * T.sizeof);