NSArray vs NSDictionary查找

时间:2012-06-12 14:15:31

标签: iphone cocoa-touch ios5 ios4 cocos2d-iphone

检查列表中是否已存在对象更快,更便宜。通过使用NSArray包含对象或检查NSDictionary是否已存在密钥?

NSArray containsObject选择器是否也遍历整个数组元素?那么检查字典中是否已存在密钥呢?这是否需要遍历所有键。

最后,检查一个对象(同一类的对象)中是否已存在对象的最佳和最快方法是什么。

提前致谢

3 个答案:

答案 0 :(得分:4)

根据Collection Classes的文档,NSDictionary基于HashTables。这意味着如果您在字典中搜索某个键,则所需的时间比迭代数组要少。

因此,搜索密钥应为o(1 + numberofcollisions)。迭代数组的是o(n)。你可以快速排序数组,然后二进制搜索它,这将使成本少得多。然而,对于你来说,NSDictionary(哈希表)非常便宜搜索。

来自Apple docs

  
    

在内部,字典使用哈希表来组织其存储,并提供对给定相应密钥的值的快速访问。但是,为字典定义的方法使您免受使用哈希表,散列函数或键的散列值的复杂性的影响。这些方法直接使用键,而不是以散列形式。

  

答案 1 :(得分:0)

我想说最快的方法是在插入对象时对数组进行排序:

NSMutableArray *myArray;

[myArray addObject:someCustomObject];
[myArray sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    // custom compare code here
}];

虽然这会在插入对象时降低性能,但会大大增加查找时间。

在NSArray上进行二进制搜索:

BOOL binarySearchContains(NSArray *sortedArray, id object, NSComparator comparisonBlock)
{
    // simple recursive helper function
    __block BOOL (^_binaryRecurse)(NSArray *, id, int lo, int hi) = ^BOOL(NSArray *array, id object, int lo, int hi)
    {
        int middleIndex = ((hi - lo) / 2) + lo;

        if (hi == lo || middleIndex < 0 || middleIndex >= [array count])
            return NO;

        int compareResult = (comparisonBlock(object, [array objectAtIndex:middleIndex]));

        if (compareResult < 0)
            return _binaryRecurse(array, object, lo, middleIndex - 1);
        if (compareResult > 0)
            return _binaryRecurse(array, object, middleIndex + 1, hi);

        return YES;
    };

    return _binaryRecurse(sortedArray, object, 0, [sortedArray count]);
}

在我的测试中,bsearch-containsObject:快约15倍。

答案 2 :(得分:0)

你在谈论多少个值?速度的差异可能是无关紧要的,因此选择是在代码中最有意义的选择。事实上,这应该是第一优先,除非你知道存在速度问题。

简短版本:除非您特别需要,否则请使用NSDictionary。