0

In my app I have to store path points into an array and then follow those points. To get a smoother run I usually have to dump a path into 5k points. This means I have to store 10k floats- 5k for x and 5k for y coordinates. Right now this is what I'm doing:

1.In the view load I initialize an NSArray with those 10k numbers like this:

pathPoints=[NSArray arrayWithObjects:[NSNumber numberWithFloat:-134.8427],  [NSNumber numberWithFloat:148.8433], ....... and so on];
  1. And then I read it like this:

    int currentXIndex=..////

    [[pathPoints objectAtIndex:currentXIndex] floatValue];

    [[pathPoints objectAtIndex:currentXIndex+1] floatValue];

As you can see, each time when I need the next position? I have to unbox it(cast it from NSNumber to float). And I'm sure this takes a great deal of performance. Any suggestions how I can do this another, more performant way?

Mikayil Abdullayev
  • 12,117
  • 26
  • 122
  • 206

4 Answers4

2

For a simple container, I'd use a C array and traverse with pointers. Remember that Objective C is a superset of C, so you have everything right there for when the need arise.

edit; sample code:

you don't have to store all numbers 'naked', a struct don't have any overhead:

typedef struct tCoords {
    float x, y;
} tCoords;

then just malloc() the size needed:

arraySize = 5000;
tCoords *array = malloc(arraySize * sizeof(tCoords));

and iterate like any simple array:

tCoords *end = array+arraySize;

for (tCoords *p = array; p<end; ++p) {
    float x = p->x;
    float y = p->y;
}

If you don't like the "old C" look of the code, it's easy to encapsulate all this in a class that 'owns' the array (don't forget to free() it when disposed)

Javier
  • 60,510
  • 8
  • 78
  • 126
  • could you please give me little code sample as to how I can do that. I've tried to do it the plain C way, but unfortunately don't know how. – Mikayil Abdullayev Nov 10 '12 at 17:36
  • I would use this C array approach. Its also likely useful to run the performance tools to see where your bottle necks really are. Use the sampler on your code running on real iphone hardware, hopefully a 3GS, or whatever base model you plan on supporting. iPhone 5s are pretty fast - too fast for figuring out how your code might behave in many instances. – Tom Andersen Nov 10 '12 at 19:38
1

You can reduce in half the amount of wrapping reasonably cheaply by using [NSValue valueWithPOint:(CGPoint...)] method to box a pair of coordinates as one id object instead of two. This should also reduce the memory required to store the pairs.

If this is not enough, you could "bundle" more elements together in a single wrapper. For example, if you know that your paths are created in groups of, say, 32 points, you can store arrays of 32 CGPoint objects wrapped in NSData (use [NSData dataWithBytes:.. length:..] method). When you need a point at index i, grab a group at index i/32 from NSArray, unwrap from NSData, and then take element at i%32.

If everything else fails, make a class to represent an array of CGPoint structures by hiding calls of malloc and free behind a nice-looking Objective C interface.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

Use a plain array instead of NSArray?

float *pathPoints;
pathPoints = new float[10000];
...
...
delete [] pathPoints;

Or for a constant array

float pathPoints [] = {-134.8427,148.8433, ... and so on};
Brian
  • 6,717
  • 2
  • 23
  • 31
  • Does this method require that I put this pointer into the same place where I will use it? With NSArray I can have it in another class, call a class method that will return that array and use it.I think I won't be able to send a C pointer to a method, will I? – Mikayil Abdullayev Nov 10 '12 at 17:44
0

you could use a C array of floats...

for info on C arrays:

Resizing an array with C

Community
  • 1
  • 1
Daij-Djan
  • 49,552
  • 17
  • 113
  • 135