I’ve got a lot of objects, every one has some tags, which are stored in NSDictionary. I’ve also got a loop, in which I’m iterating through all objects and do some stuff depending on object’s tags. Method objectForKey: worsens performance a lot, if there are too many calls of it. How can I improve the performance? I’ve tried, for example, set “strong” instead of “copy” into @property, but that did not solve problem. Thanks!
EDITED:
Here is some kind of code, it is much more simple than the one in my project, of course. The Profiler says that the hot spots are in objectForKey:, not in doSomeStuff:. Can It be because of amount of its calls? Tags have got few objects, about 10 for each object, but the amount of objects is rather large
.h:
@interface MyObject : NSObject
@property (nonatomic, readwrite, strong/*copy*/ ) NSDictionary *tags;
-(void)doSomeStuff;
@end
.m:
@implementation MyObject
{
NSDictionary *tags; // about 10 values for each object
}
-(NSDictionary *)tags
{
return tags;
}
-(void)setTags:(NSDictionary *)newTags
{
tags = [newTags copy];
}
-(void)doSomeStuff;
@end
using:
NSArray *objects = ... // a lot of items, > 1000
NSArray *rules = ... // NSArray of objects with property NSArray* Strings, about 50 strings
for (MyObject *object in objects)
{
for (NSArray *rule in rules)
{
for (NSString *ruleString in rule.Strings)
{
// there is a more complicated check in my project, so you may imagine that there are 10 calls of objectForKey:, with different keys
if ([object objectForKey:ruleString] isEqualToString:@"yes"])
{
[object doSomeStuff];
}
}
}
}
If
objectForKeyis slow, your best bet might well be to create a custom (more efficient) implementation ofhashfor the objects that you’re adding. It’s possible that the default implementation is creating lots of clashes which is likely to affect performance.Having said that, you don’t say how many objects you’re adding, what you’re doing with them or what environment you’re using. It’s difficult to say much more than guess. In general, NSDictionary is pretty efficient.
Edit: To clarify based on the extra information you added… I don’t think this is about improving the performance of NSDictionary. Given your numbers, you’re calling
objectForKey:over half a million times; of course this is going to be the most demanding operation. You need to think about optimising your algorithm (pre-computing?) rather than trying to making something that’s already quick very slightly faster.