Reputation: 7234
I did some runs on my iOS app with Instruments and I saw that 90% of the load on the main thread on launch (about 1000ms total) is caused by containsObject: calls. That's on the main thread and I don't think it's cool.
Is there a faster alternative to this method? An algorithm or another method?
Any suggestions?
MORE INFO:
I looked into my code again I realized that in fact I don't need to know the order of the objects, only if an object is part of that set. Which means NSSet will do just fine (and I guess is faster).
Number of objects - there may very well be 1000+ objects in that set.
Upvotes: 7
Views: 3195
Reputation: 32066
If you NEED to use an array, skip a bit further down
Your other options might include:
Using an NSDictionary
which uses key->value pairs which (I expect will) have O(1) read complexity at the cost of extra storage space for the keys
If you aren't using duplicates and order isn't important, using an NSSet
will offer better read complexity (I don't know what the complexity will be, the docs probably will)
If you keep the array sorted, searching can be done in O(log n)
time instead of O(n)
as you can take advantage of a binary search.
Caveat Lector: This was written from memory
-(void) /*adding*/
{
int proposedIndex = 0;
proposedIndex = [array indexOfObject:node
inSortedRange:NSMakeRange(0, array.count)
options:NSBinarySearchingInsertionIndex
usingComparator:
^ NSComparisonResult(id obj1, id obj2)
{
if (obj1.valueToCompare < obj2.valueToCompare) return NSOrderedAscending;
if (obj1.valueToCompare > obj2.valueToCompare) return NSOrderedDescending;
else return NSOrderedSame;
}];
[array insertObject:node atIndex:proposedIndex];
}
-(id) /* Getting */
{
int location = [array indexOfObject:node
inSortedRange:NSMakeRange(0, array.count)
options:NSBinarySearchingFirstEqual
usingComparator:
^ NSComparisonResult(id obj1, id obj2)
{
if (obj1.valueToCompare < obj2.valueToCompare) return NSOrderedAscending;
if (obj1.valueToCompare > obj2.valueToCompare) return NSOrderedDescending;
else return NSOrderedSame;
}];
if (location == NSNotFound) return nil;
return [array objectAtIndex:location];
}
Upvotes: 11