Mac / iPhone App Development
Home of a Small Time Developer

Dynamic Arrays with C

In the final push to add syntax highlighting to iVersion I have been working on optimising the parser.

In the inner parsing loop I have been using the standard NSMutableArray to keep track of various objects and tokens. Objective C message passing is of course an order of times slower than a C function call, even if purely for the fact that they can’t be inlined. A great article that explains more about the objective c runtime an be found on the cocoa samurai blog

So I decided to drop down to a dynamic array using plain C. However even though I’m sure dynamic arrays have been implement thousands of times I couldn’t seem to find any simple implementations.

//** Usage
//Create an array with capacity 2
CArray * array = CArrayInit(2);

//Add two buckets
CArrayAdd(array, "test");
CArrayAdd(array, "another test");

//Add another and it will resize accordingly
CArrayAdd(array, "yet another");

//Print All
for (int ii = 0; ii < array->count; ++ii)
{
        const char * buffer = CArrayObjectAtIndex(array, ii);
        printf("Index: %d - %s\n", ii, buffer);
}

Download:

CArray.h

CArray.c

Notes:
The following test function usually reports about 5x faster than NSMutableArray which I think is a credit to how efficient the Objective C library and messaging system really is considering all the things your missing out on (exceptions, null pointers etc)

void CArrayTestRoutine()
{

    CArray * array = CArrayInit(0);

    NSTimeInterval start = [[NSDate date] timeIntervalSince1970];
    NSString * test;

    for (int ii = 0; ii < 10000000; ++ii)
    {
        CArrayAdd(array, @"test");
        test = CArrayObjectAtIndex(array, CArrayCount(array)-1);
    }

     CArrayRemoveObjectAtIndex(array, 0);

     NSTimeInterval end = [[NSDate date] timeIntervalSince1970];
     printf("CArray 100,000,000 Elements took %fs\n", end-start);

     NSMutableArray * nsarray = [[NSMutableArray alloc] initWithCapacity:0];
     start = [[NSDate date] timeIntervalSince1970];
     NSString * string;

     for (int ii = 0; ii < 10000000; ++ii)
    {
        [nsarray addObject:@"test"];
        string = [nsarray objectAtIndex:[nsarray count]-1];
    }

    [nsarray removeObjectAtIndex:0];

     end = [[NSDate date] timeIntervalSince1970];
    [nsarray release];
     printf("NSMutableArray 100,000,000 Elements took %fs\n", end-start);

     printf("%s\n", [string UTF8String]);
     printf("%s\n", [test UTF8String]);
     CArrayDestroy(array);

}

Leave a Reply