Performance issues with NSMutableArray and NSArray

2019-08-06 09:16发布

问题:

I've been programming C/C++ for 20 years but I'm new to objective-c and Coco and have some questions about the performance of NSMutableArray and NSArray.

I need an container much like the stl list container, but coco doesn't seem to have one and inserting and removing elements from the middle of MSMutableArray seems slow, but treating it like a stl vector isn't that fast either.

Also, MSMutableArray seems to only store Objects, so keep tracking of a simple data type line int or float incurs additional overhead of creating Objects to store them in.

I'm currently writing a game and performance is critical. I can always drop into C++ for the guts of my game engine, but there is so much about objective-c that I like and I'd hate to abandon it.

Are there fast stl like containers for objective-c that I should be using?

Is there any good online documentation about how these are implemented so I can try and figure put why performance is so slow?

Thanks!

回答1:

The foundation collection classes like NSMutableArray aren't guaranteed to use any specific implementation, and in fact I believe they will actually change their data structure to optimize speed for the number of items they contain. You can read more here, but basically I wouldn't worry about the underlying algorithm.

You could create your own data structure in C (or go the Objective-C++ route if you want), which would save the memory and performance overhead of wrapping each primitive in an NSNumber. Of course, you'll want to run the performance tools first to make sure this is really where the problem lies, and you're not just wasting your time.



回答2:

If you really cares about performance, I recommend to avoid using Foundation data structures via Objective-C as the runtime system eliminates all opportunities for compile-time optimization, and as you've said you always need to box primitives.

You can just use Objective-C++ and use std::list<id>.

If you must use Objective-C, see CHDataStructures, which contains the CHSinglyLinkedList type.



回答3:

running this simple two side access test on a real ipad device:

NSMutableArray vs. float*, C type float* is 109 times faster!, so if performance is an issue figures are quite clear.

-(void)testSpeedNSArrayvsFloat {
const int n=1000000;
NSMutableArray*a=[NSMutableArray arrayWithCapacity:n];

NSTimeInterval tn, tf;
NSDate *t=[NSDate date];
for (int i=0; i<n; i++) {
    a[i]=[NSNumber numberWithFloat:i];
    float _f=[a[i] floatValue];
}
NSLog(@"%d nsarray number: %f",n, tn=-[t timeIntervalSinceNow]);

t=[NSDate date];
float*fa=calloc(n, sizeof(float));
for (int i=0; i<n; i++) {
    fa[i]=i;
    float _f=fa[i];
}

NSLog(@"%d float number: %f",n, tf=-[t timeIntervalSinceNow]);
NSLog(@"Ratio %f",tn/tf);
free(fa);

}

2018-10-17 14:25:05.312866+0200 voiceXplorer[500:171209] 1000000 nsarray number: 1.699707 2018-10-17 14:25:05.328571+0200 voiceXplorer[500:171209] 1000000 float number: 0.015554 2018-10-17 14:25:05.328699+0200 voiceXplorer[500:171209] Ratio 109.278151