NSArray Vs C Array


#1

Hi all,

Nice chapter. :slight_smile:

Just a question - I see with C arrays it’s nice to hold arrays with numbers / floats etc

We can do the same with an NSArray (NSNumberWithFloat or NSNumberWithInt I believe.

So, why would we use a C array over an NSArray?

Thanks!


#2

C arrays take up less space and they are much faster.

Run some experiments:

//  main.m

#import <Foundation/Foundation.h>

// --------------------------------------------------
//
// Courtesy of pretty-function.org
//
@interface MyTiming: NSObject
+ (void)start;
+ (double)elapsedTimeInMicroSeconds;
@end

#define USE_C_ARRAYS 0
#define LOAD 1

// --------------------------------------------------
//
int main (int argc, const char * argv[])
{
    @autoreleasepool {
        typedef unsigned long number_type;
        const number_type N = LOAD * 1000000;
        [MyTiming start];
#if USE_C_ARRAYS
        NSLog (@"Using C array...");
        number_type *numbers = malloc (N * sizeof (number_type));
        for (number_type x = 0; x < N; ++x) {
            numbers [x] = arc4random_uniform (1024);
        }
#else
        NSLog (@"Using NSArray array...");
        NSMutableArray *numbers = [NSMutableArray array];
        for (number_type x = 0; x < N; ++x) {
            [numbers addObject:[NSNumber numberWithLong:arc4random_uniform (1024)]];
        }
#endif
        NSLog (@"Elapsed time: %f microseconds", [MyTiming elapsedTimeInMicroSeconds]);
        
        NSLog (@"Sleeping for 30 seconds...");
        sleep (30);
        NSLog (@"Done.");
    }
    return 0;
}

// --------------------------------------------------
//
// Courtesy of pretty-function.org
//
@implementation MyTiming

#include <sys/resource.h>

static struct rusage t1;

+ (void)start
{
    getrusage (RUSAGE_SELF, &t1);    
}

+ (double)elapsedTimeInMicroSeconds;
{
    struct rusage t2;
    getrusage (RUSAGE_SELF, &t2);
    double v = ((double) (1000000)) * (double) (t2.ru_utime.tv_sec - t1.ru_utime.tv_sec)
    + (double) (t2.ru_utime.tv_usec - t1.ru_utime.tv_usec);
    return v;
}

@end

By compiling with different values of the following parameters

//  compile with 0 or 1
#define USE_C_ARRAYS 0

//  compile with 1, 10, or 100
#define LOAD 1

Run the program from the command line, and monitor the memory usage of its process with the Activity Monitor app.

Compare the elapsed times and memory usages.


#3

That really doesn’t answer the question as it suggests that one should never use NSArray, begging the question as to why NSArray exists.