Array append performance 2

Denis Koroskin 2korden at gmail.com
Mon Sep 1 01:53:58 PDT 2008


On Mon, 01 Sep 2008 01:11:46 +0400, bearophile <bearophileHUGS at lycos.com>  
wrote:

> Fawzi Mohamed:
>> I had not thought about an important thing: the content of the array
>> can change... so copying is safer.
>
> Yes, and there are other problems, that make the situation/code a mess,  
> so I copy all items now, keeping code simpler. I'm  
> debugging/benchmarking it now...
>
> Later,
> bearophile

Please, test my version, too!
While it is slighly slower, it allows appending invariant arrays (i.e.  
strings) without copying data (although it is currently not implemented).

An idea is to store an array (or a list) of invariant elements.
Current buffer is mutable until it is completely full. It then casted to  
invariant and appended to the list and an new mutable buffer (of a higher  
size) created.

struct ArrayBuilder(T) {
     //private BearophileArrayBuilder!(invariant(T[])) subArrays;
     private invariant(T[])[] subArrays;
     private int lengthSoFar;
	
     private T[] tmpArray;
     private int curOffset = 0;

     void opCatAssign(T x) {
         int capacity = tmpArray.length;
         if (curOffset >= capacity) {
             int old_capacity = capacity;

             if (capacity == 0)
                 capacity = 4; // starting point not too much small
             else if (capacity < (1 << 26)) // 67_108_864
                 capacity *= 2; // for amortized O(1) and less RAM  
fragmentation
             else
                 capacity *= 1.3; // slower growing rate to save RAM

             if (old_capacity != 0) {
                 subArrays ~= cast(invariant(T[]))tmpArray;
             }

             tmpArray = new T[capacity];
			curOffset = 0;
         }

         tmpArray[curOffset] = x;
         assert(tmpArray[curOffset] == x);
         ++curOffset;
         ++lengthSoFar;
     }

     ///
     T[] toarray() {
         T[] array = new T[lengthSoFar];
         int offset = 0;
         foreach (subArray; subArrays) {
             int newOffset = offset+subArray.length;
             array[offset..newOffset] = subArray[];
             offset = newOffset;
         }
         array[offset..$] = tmpArray[0..curOffset];
         return array;
     }
}



More information about the Digitalmars-d mailing list