微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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.

原文地址:https://www.jb51.cc/c/115625.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐