NSMutableDictionary比Java Map慢得多......为什么?

时间:2015-07-15 20:40:17

标签: objective-c performance

下面的代码将简单值持有者映射到一个对象,使用XCode 7 beta3,#14;最快,积极优化[-Ofast]"在Java中的运行速度比Objective-C快15倍。我可以在Java中获得超过280M查询/秒,但在objc示例中只能获得大约19M。 (我在这里发布了相应的Java代码,因为它起初是一个Swift比较:Swift Dictionary slow even with optimizations: doing uncessary retain/release?)。

这是我的实际代码的简化版本,它肯定受哈希查找时间的约束,并且也展示了这种整体性能差异。在下面的测试中,我测试null的值只是为了确保编译器不会优化掉查找,但在实际应用中我会在大多数情况下使用该值。

当我查看乐器时,我发现在保留/释放,msgSend以及一些我不理解的锁定调用上花费了大量时间。

任何可以解释这个问题的想法比Java或任何变通方法慢10-15倍,我们将不胜感激。我实际上可以像下面那样实现一个完美的哈希,所以我可以使用一个快速的int-object字典来获取iOS。

product

2 个答案:

答案 0 :(得分:2)

您可以重新实现这样的-isEqual:方法以避免属性访问者:

- (BOOL) isEqual:(id)other
{
    return _xi == ((MyKey*)other)->_xi;
}

如果您的MyKey类可能是子类,那是不可接受的,但我从Java代码中看到该类有final

答案 1 :(得分:1)

NSMutableDictionary的计算复杂性是下一个(来自CFDictionary.h文件):

The access time for a value in the dictionary is guaranteed to be at
worst O(N) for any implementation, current and future, but will
often be O(1) (constant time). Insertion or deletion operations
will typically be constant time as well, but are O(N*N) in the
worst case in some implementations. Access of values through a key
is faster than accessing values directly (if there are any such
operations). Dictionaries will tend to use significantly more memory
than a array with the same number of values.

意味着,几乎所有的时间都应该具有访问/插入/删除的O(1)复杂性。对于Java HashMap,你应该得到几乎相同的东西。

根据this研究,使用dictionaryWithCapacity:便利初始化程序没有任何好处。

如果您使用整数作为键,可能可以用数组替换字典。

在此WWDC session中,他们解释了objc_msgSend性能问题以及如何处理它们。 第一种解决方案是使用C ++和STL容器。第二个是使用Swift,因为与Objective-C不同,它只是当它注意到时才是动态的。