提问者:小点点

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


下面的代码将简单的值持有者映射到一个对象,它在Java中的运行速度比使用XCode 7 beta3“最快、积极的优化[-ofast]”的Objective-C快15倍以上。在Java中,我可以获得超过280m/sec的查找,但在objc示例中只有大约19m。(我在这里发布了相应的Java代码,因为这是作为一个Swift比较开始的:Swift Dictionary即使经过优化也很慢:是否不断保留/发布?)。

任何关于为什么会比Java慢10-15倍的想法或任何变通方法都将不胜感激。我实际上可以实现一个完美的哈希,就像下面的哈希一样,这样我就可以在iOS上使用一个快速的int-object字典,如果我能找到的话。

@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]);
    }

共1个答案

匿名用户

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

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

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