以下代码将简单的值保持者映射到一个对象,使用 XCode 7 beta3 的 Java 运行速度比 Objective-C 快了15倍以上,“最快,最激进的优化[-Ofast]”。在 Java 中,我可以获得超过280M的查找/秒,但在 objc 示例中只有大约19M(我在此发布了相应的 Java 代码,因为这是一个 Swift 比较:Swift Dictionary slow even with optimizations: doing 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]);
}
xi
属性声明为nonatomic
吗?你没有声明任何属性,这意味着该属性默认为atomic
。 - Ewan Mellor