0

コレクション演算子でvalueForKeyPathを使用することと、コレクションを1つずつループして手動で計算することのパフォーマンスの違いを知っている人はいますか?例えば:

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

vs

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

何かご意見は?

4

3 に答える 3

3

あなたの質問は、収集演算子の一般的な使用法の誤解に基づいていると思います。一般的な使用法はコアデータであり、オブジェクト全体に障害を発生させることなく、データをSQLでより効率的に蓄積できます。

NSSet私の経験では、単純なループはメモリ内またはNSArrayバッキングストアの方がはるかに高速です。

于 2012-09-10T20:34:31.163 に答える
1

セットの古典的な実装の1つは、キーに基づくハッシュマップを使用するため、最初の実装の方が高速であると思われます。これにより、キーによるルックアップが手動のO(n)実装に対してO(1)アルゴリズムになります。

そうは言っても、簡単な実験に勝るものはありません。NSSetに数千の値をロードして、どちらが高速かを確認します。

于 2012-09-10T20:27:38.580 に答える
0

1000万人のメンバーを使用したテスト条件下で、2番目の方法である単純なループの方が高速であることがわかりました。0秒対32秒です。メンバーが100万人の場合、0秒対3秒でした。これは、すべてのデータがメモリ内にあることを前提としており、RobNapierの経験と一致しています。テストコードは次のとおりです。

- (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 に答える