views:

147

answers:

5

Hi all, I have 2 NSArray (Mutable, actually) that I am trying to convert to a C-style double array for a c routine i am passing them to.

Here is my Objective-C routine:

NSMutableDictionary *childDictionary = [myParentDictionary objectForKey:resort_code];

latitudeArray = [childDictionary objectForKey:@"lat"];
longitudeArray = [childDictionary objectForKey:@"lon"];

int nvert = [latitudeArray count];
double laArray[nvert];
double loArray[nvert];

for(int i=0; i<nvert; i++) {
    double dLat = [[latitudeArray objectAtIndex:i]doubleValue];
    double dLon = [[longitudeArray objectAtIndex:i]doubleValue];
    laArray[i] = dLat;
    loArray[i] = dLon;
}

This takes upwards of 3-8 seconds on the 3G iPhone (instantaneous on the simulator -- yet another reason to test on the device )

is there faster way? I have to end up with laArray[i] and loArray[i] as c-style arrays of doubles.

(to expand on the question for the benefit of a commenter): Each array consists of @"38.448745" (lat) and @"-122.9847684" (lon) style content. I do this cos to be pushed onto an NSArray, the lat and lon need to be objects. I simply used:

[latitudeArray addObject:[NSString stringWithFormat: @"%.10f",dlat]];
[longitudeArray addObject:[NSString stringWithFormat: @"%.10f",dlon]];

I suppose I could change that to:

[latitudeArray addObject:[NSNumber numberWithDouble: @"%.10f",dlat]];
[longitudeArray addObject:[NSNumber numberWithDouble: @"%.10f",dlon]];

...which may reduce the conversion time of

double dLat = [[latitudeArray objectAtIndex:i]doubleValue];

but wouldn't I still need that exact line to convert from NSString to double? It just may work faster?

thx

A: 

Possibly using fast iteration, but I doubt that will really speed up your loop.

Mr-sk
+2  A: 

For the general case of converting an NSArray to a C array, you can use getObjects:. In this case, though, want you actually want is not to convert the NSArray, but to derive an array of doubles from an NSArray of some unspecified object type.

One obvious way to speed things up would be fast enumeration rather than sending a message to get the object for each iteration of the loop. I suspect the real solution, though, is outside your algorithm. The slowness probably comes from transforming whatever objects the array contains into doubles, in which case you'll need to find a way around that — maybe store doubles all along, maybe do the conversion in the background, etc. If you're creating the arrays yourself and there isn't some compelling reason for the objects to be strings, you should use NSNumbers instead. Those should be quite a bit faster.

Chuck
+2  A: 

I suspect you have an array of strings like @"213.12385" that need to be parsed and converted when you call doubleValue on them. If that is where the issue is, the C arrays have nothing to with this.

Only thing I would add here is to throw Shark on this and see where it's spending it's time. If it's spending time in doubleValue find a different way to parse the strings with preprocessing in background or something. If it's in objectAtIndex: perhaps fast enumeration would help. If it's somewhere else entirely then you know it's not this snippet that's slow.

Squeegy
+2  A: 

dlat is a double, right?

So instead of:

[latitudeArray addObject:[NSString stringWithFormat: @"%.10f",dlat]];

Do:

[latitudeArray addObject:[NSNumber numberWithDouble:dlat]];

They both respond to doubleValue but the NSNumber should not have to do any string parsing since it's stored as a numeric value already. And you never have to go to a string at all.

Squeegy
A: 

The best solution is probably to make sure those values never end up in an NSArray as NSString values. I would attack this at the source.

So you edited your question and added that you are actually building those arrays. So why not use native arrays of doubles or floats from the start? I usually recommend against this but in your case it sounds like there is a huge performance gain.

St3fan