Fast way to store and retrieve pairs of numbers in Objective-C

☆樱花仙子☆ 提交于 2019-12-10 16:08:02

问题


I am implementing queued flood fill algorithm and need to store and retrieve pairs of numbers in NSMutableArray.

Basically, I am creating an array

m_queue = [NSMutableArray array];

then at some time I populate the array

[m_queue addObject:[NSValue valueWithCGPoint:CGPointMake(x + 1, y)]];

then I retrieve data for the next iteration and remove the value at the beginning of the array

NSValue* value = [m_queue objectAtIndex:0];
[m_queue removeObjectAtIndex:0];
CGPoint nextPoint = [value CGPointValue];

[self queueFloodFill8:nextPoint.x y:nextPoint.y];

The question is: what can I do to avoid creating large number of CGPoint and NSValue objects?

I don't really need points, the algorithm uses pairs of integer values, so I think there might be a better way to store such pairs.

UPDATE: I looked into implementing C-style solution like @mattjgalloway and @CRD suggested.

I've introduced

typedef struct lookup_point_struct
{
    int x;
    int y;
    struct lookup_point_struct* next;
} LookupPoint;

and have rewritten code to use linked list of such structs instead of NSMutableArray and CGPoint/NSValue.

All this made my code about 3 times faster. And memory consumption dropped significantly too.


回答1:


There wouldn't really be a better Objective-C / Foundation way of doing it, apart from maybe creating your own class such as NumberPair or something which you put into the array rather than using NSValue and CGPoint. It might be slightly more memory efficient to do that and you could make NumberPair contain two integers rather than floats like you are concerned about. Something like:

@interface NumberPair : NSObject
@property (nonatomic, assign) int x;
@property (nonatomic, assign) int y;
@end

@implementation NumberPair
@synthesize x, y;
@end

...

m_queue = [NSMutableArray array];

NumberPair *newPair = [[NumberPair alloc] init];
newPair.x = 1;
newPair.y = 2;
[m_queue addObject:newPair];

...

NumberPair *nextPoint = [m_queue objectAtIndex:0];
[m_queue removeObjectAtIndex:0];
[self queueFloodFill8:nextPoint.x y:nextPoint.y];

Other than that you could do a more C-like thing of having a struct containing two integers, create a dynamically allocated array to store the structs (you'd need to know the max size of the queue or keep reallocating). Something like:

typedef struct {
    int x;
    int y;
} NumberPair;

NumberPair *m_queue = (NumberPair*)malloc(sizeof(NumberPair) * QUEUE_SIZE);
// ... etc

Also, you might want to check out my MJGStack class which wraps NSMutableArray to provide a stack like interface which you might be able to adjust slightly to do what you want rather than using NSMutableArray directly. Although that's not essential by any means.




回答2:


How large do you expect your m_queue array to get?

If the cost of the NSMutableArray and NSValue objects (CGPoint is a struct, no real cost there) is impacting your algorithm then consider using a C-style array of structs as a circular buffer together with two indexes for front/back of the queue. You can abstract this into a queue class (or an adt using functions to save on dynamic method call overhead if you need to).

If you need to deal with an unbounded queue you can malloc & realloc the array with your queue class/adt as needed (which is essentially what NSMutableArray does behind the scenes but with more overhead for its generality).



来源:https://stackoverflow.com/questions/9110009/fast-way-to-store-and-retrieve-pairs-of-numbers-in-objective-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!