Optimizing a for in loop with NSMutableDictionary
I have an NSMutableDictionary that contains a MPMediaItem and a string of it's title for it's key. I currently have 1,777 items in the dictionary.
I am looping through the dictionary looking for a fuzzy match with a supplied NSString. How can I speed it up? It takes about 6 seconds every time it's run.
I'll just past in the loop itself
@au开发者_开发技巧toreleasepool {
float currentFoundValue = 1000.0;
NSMutableArray *test;
MPMediaItemCollection *collection;
float match;
for(id key in artistDictionary)
{
NSString *thisArtist = key;
int suppliedCount = [stringValue length];
int keyCount = [thisArtist length];
if(suppliedCount > keyCount)
{
match = [StringDistance stringDistance:thisArtist :stringValue];
} else {
match = [StringDistance stringDistance:stringValue :thisArtist];
}
if(match < currentFoundValue)
{
currentFoundValue = match;
test = [artistDictionary objectForKey:thisArtist];
collection = [[MPMediaItemCollection alloc] initWithItems:test];
}
}
...
See -enumerateKeysAndObjectsWithOptions:usingBlock:
, and use the NSEnumerationConcurrent
option.
You have two performance bootle necks:
- You potentially recreate the
MPMediaItemCollection
instance once for each iteration, when only the last one created is needed. - -[NSDictionary enumerateKeysAndObjectsWithOptions:usingBlock:] is much faster when both the key and value of the enumerated dictionary is needed.
Change into something like this:
float currentFoundValue = 1000.0;
NSMutableArray *test = nil;
MPMediaItemCollection *collection;
float match;
[artistDictionary enumerateKeysAndObjectsWithOptions:NSEnumerationConcurrent
usingBlock:^(id key, id obj, BOOL *stop)
{
NSString *thisArtist = key;
int suppliedCount = [stringValue length];
int keyCount = [thisArtist length];
if(suppliedCount > keyCount)
{
match = [StringDistance stringDistance:thisArtist :stringValue];
} else {
match = [StringDistance stringDistance:stringValue :thisArtist];
}
if(match < currentFoundValue)
{
currentFoundValue = match;
test = obj;
}
}];
collection = [[MPMediaItemCollection alloc] initWithItems:test];
精彩评论