在此算法中填充NSArray的最佳方法

时间:2012-10-23 02:11:53

标签: objective-c ios arrays nsarray

我打算制作一个执行以下操作的程序:

Create an NSArray populated with numbers from 1 to 100,000.
Loop over some code that deletes certain elements of the NSArray when certain conditions are met.
Store the resultant NSArray.

然而,上述步骤也将循环多次,因此我需要一种快速的方法来制作具有100,000个数字元素的NSArray。

那么最快的方法是什么?

是否有使用for循环迭代填充数组的替代方法?比如NSArray方法可以为我快速做到这一点?

或许我可以通过任何方式第一次使用100,000个数字制作NSArray。然后使用方法arraywithArray创建每个新的NSArray(步骤1)? (这是更快捷的方式吗?)

或许你有一些完全不同的东西可以达到我想要的目的。

编辑:在上面的帖子

中用NSMutableArray替换NSArray

5 个答案:

答案 0 :(得分:3)

很难预先知道哪种方法最快。我喜欢基于块的功能,例如

NSMutableArray *array = ...; // your mutable array

NSIndexSet *toBeRemoved = [array indexesOfObjectsPassingTest:^BOOL(NSNumber *num, NSUInteger idx, BOOL *stop) {
    // Block is called for each number "num" in the array.
    // return YES if the element should be removed and NO otherwise;
}];
[array removeObjectsAtIndexes:toBeRemoved];

您应该从正确运行的算法开始,然后使用Instruments进行性能分析。

答案 1 :(得分:2)

我很确定使用c数组创建数组最快,然后从中创建NSArray(即将推出基准测试)。根据您想要删除数字的方式,在初始循环中执行此操作可能是最快的:

const int max_num = 100000;
...
id *nums = malloc(max_num * sizeof(*nums));
int c = 0;
for(int i = 1; i <= max_num; i++) {
    if(!should_skip(i)) nums[c++] = @(i);
}
NSArray *nsa = [NSArray arrayWithObjects:nums count:c];

第一个基准有点令人惊讶。对于100M对象:

NSArray alloc init:             8.6s
NSArray alloc initWithCapacity: 8.6s
id *nums:                       6.4s

所以数组更快,但不如我预期的那么多。

答案 2 :(得分:2)

您可能需要查看NSMutableIndexSet。它旨在有效地存储数字范围。

您可以像这样初始化它:

NSMutableIndexSet *set = [[NSMutableIndexSet alloc]
    initWithIndexesInRange:NSMakeRange(1, 100000)];

然后你可以像这样从中删除123:

[set removeIndex:123];

或者你可以像这样删除400到409:

[set removeIndexesInRange:NSMakeRange(400, 10)];

您可以像这样遍历集合中的所有剩余索引:

[set enumerateIndexesUsingBlock:^(NSUInteger i, BOOL *stop) {
    NSLog(@"set still includes %lu", (unsigned long)i);
}];

或者更有效率,像这样:

[set enumerateRangesUsingBlock:^(NSRange range, BOOL *stop) {
    NSLog(@"set still includes %lu indexes starting at %lu",
        (unsigned long)range.length, (unsigned long)range.location);
}];

答案 3 :(得分:0)

您可以使用快速枚举来搜索数组。

for(NSNumber item in myArrayOfNumbers)
{
   If(some condition)
   {
        NSLog(@"Found an Item: %@",item);
    }
}

答案 4 :(得分:0)

你可能想重新考虑一下你在这做什么。问问自己为什么要这样的阵列。如果你的目标是操纵任意大的整数集合,你可能更愿意使用NSIndexSet(和它的可变对应物)。

如果您真的想以最有效的方式操作NSArray,您将需要实现一个专门为此类作业优化的专用子类。