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

Pat*_*yer 10 performance objective-c

下面的代码将简单的值持有者映射到一个对象,使用XCode 7 beta3,"最快,最具侵略性的优化[-Ofast]",在Java中的运行速度比Objective-C快15倍.我可以在Java中获得超过280M查询/秒,但在objc示例中只能获得大约19M.(我在这里发布了相应的Java代码,因为这开始是一个Swift比较:Swift Dictionary甚至在优化时缓慢:执行uncessary retain/release?).

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

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

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

@interface MyKey : NSObject <NSCopying>
    @property int xi;
@end

@implementation MyKey
    - (NSUInteger)hash { return self.xi; }
    - (BOOL)isEqual:(id)object    { return ((MyKey *)object).xi == self.xi; }
    - (id)copyWithZone:(NSZone *)zone { return self; }

@end

    NSMutableDictionary *map = [NSMutableDictionary dictionaryWithCapacity:2501];
    NSObject *obj = [[NSObject alloc] init];

    int range = 2500;
    for (int x=0; x<range; x++) {
        MyKey *key = [[MyKey alloc] init];
        key.xi=x;
        [map setObject:obj forKey:key];
    }

    MyKey *key = [[MyKey alloc] init];
    int runs = 50;
    for (int run=0; run<runs; run++)
    {
        NSDate *start = [NSDate date];

        int reps = 10000;
        for(int rep=0; rep<reps; rep++)
        {
            for (int x=0; x<range; x++) {
                key.xi=x;
                if ( [map objectForKey:key] == nil ) { NSLog(@"missing key"); }
            }
        }

        NSLog(@"rate = %f", reps*range/[[NSDate date] timeIntervalSinceDate:start]);
    }
Run Code Online (Sandbox Code Playgroud)

Ken*_*ses 2

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

- (BOOL) isEqual:(id)other
{
    return _xi == ((MyKey*)other)->_xi;
}
Run Code Online (Sandbox Code Playgroud)

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