开发者

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:

  1. You potentially recreate the MPMediaItemCollection instance once for each iteration, when only the last one created is needed.
  2. -[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];
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜