0

有谁知道将 valueForKeyPath 与集合运算符一起使用与逐个循环集合并手动进行计算之间的性能差异是什么?例如:

NSSet* myObjects = [NSSet setWithObjects:obj1, obj2, obj3, nil];
NSNumber* sum = [myObjects valueForKeyPath:@"@sum.myProperty"];

对比

NSSet* myObjects = [NSSet setWithObjects:obj1, obj2, obj3, nil];
int sum = 0;
for(MyObject* obj in myObjects)
    sum += obj.myProperty.intValue;

有什么想法吗?

4

3 回答 3

3

我相信您的问题是基于对集合运算符的常见用法的误解。常见的用途是 Core Data,数据可以在 SQL 中更有效地累积,而不必使整个对象出错。

NSSet以我的经验,简单循环对于内存或NSArray后备存储来说要快得多。

于 2012-09-10T20:34:31.163 回答
1

我怀疑第一个实现更快,因为集合的一个经典实现是通过基于键的哈希映射,从而使按键查找成为 O(1) 算法而不是手动 O(n) 实现。

话虽如此,没有什么比快速实验更好的了。用数千个值加载你的 NSSet,看看哪个更快。

于 2012-09-10T20:27:38.580 回答
0

在我对一千万成员的测试条件下,我发现第二种方法,简单循环更快——0 秒对 32 秒。拥有 100 万会员的时间是 0 秒对 3 秒。这确实假设所有数据都在内存中,并且与 Rob Napier 的经验一致。这是测试代码:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    NSMutableSet *testSet = [NSMutableSet set];
    int i = 0;
    while (i <10000000) {
        [testSet addObject:[[TestObjects alloc] init]];
        i++;
    }
    NSLog(@"%@",[NSDate date]);
    NSNumber* sum = [testSet valueForKeyPath:@"@sum.myProperty"];
    NSLog(@"%@",[NSDate date]);
    NSLog(@"%@",sum);

    NSLog(@"%@",[NSDate date]);
    long long sum2 = 0;
    for(TestObjects *obj in testSet)
        sum2 += obj.myProperty;
    NSLog(@"%@",[NSDate date]);
    NSLog(@"%lld",sum2);
    NSLog(@"%ld",testSet.count);
}

而 TestObject 在 init 中只有这个:

-(id)init {
    if (self = [super init]) {
        self.myProperty = arc4random() %100;
    }
    return self;
}
于 2012-09-11T00:21:53.540 回答