0

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

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

4

5 回答 5

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 进行分析。

于 2012-10-23T02:34:41.143 回答
2

我很确定使用 ac 数组创建数组会是最快的,然后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

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

于 2012-10-23T02:27:38.880 回答
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);
}];
于 2012-10-23T02:45:21.047 回答
0

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

for(NSNumber item in myArrayOfNumbers)
{
   If(some condition)
   {
        NSLog(@"Found an Item: %@",item);
    }
}
于 2012-10-23T02:22:16.037 回答
0

你可能想重新考虑你在这里做什么。问问自己为什么想要这样一个数组。如果您的目标是操作任意大的整数集合,您可能更喜欢使用NSIndexSet(及其可变对应物)。

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

于 2012-10-23T02:41:41.533 回答