objective-c – NSMutableDictionary比Java Map慢得多…为什么?

使用XCode 7 beta3“Fastest,Aggressive Optimizations [-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对象字典为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]);
    }

解决方法

您可以重新实现您的-isEqual:方法,以避免属性访问器:
- (BOOL) isEqual:(id)other
{
    return _xi == ((MyKey*)other)->_xi;
}

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

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...