我知道有相当多的话题似乎是关于完全相同的东西,但我没有找到真正与我想要的有关的话题。快速枚举比嵌套枚举中的for循环慢(带有测试结果)?
所以我很好奇,想要比较快速枚举到NSEnumerator和for循环的性能。 (这是要求相当频繁的部分)
首先,我比较快速计数:
for(NSNumber *number in testArray)
{
assert(number);
}
NSEnumerator:
NSEnumerator *enumerator = [testArray objectEnumerator];
NSNumber *number;
while (number = [enumerator nextObject])
{
assert(number);
}
for循环:
for(NSUInteger i = 0; i < [testArray count]; i++)
{
NSNumber *number = [testArray objectAtIndex:i];
assert(number);
}
我testArray
是一个由0到1,000,000的NSNumbers组成的数组,我在ea后100次运行测试并且计算每个测试的平均运行时间。
我也跑了他们对我的iPad 2
结果:(指所有100个运行时间)
- 0.042687s快速计数
- 0.582072s NSEnumerator
- 0.627318s for-loop
正如预期的那样,快速计数是迄今为止速度最快,而NSEnumerator仍然是一个有点快于for循环,但是这是枚举退出大阵
因此,这里的不那么频繁的问题:
其实我感兴趣的是别的东西:枚举阵列中的相互每个对象
与一个嵌套循环第一次尝试比较数组中:
for(int i = 0; i < [testArray count]-1; i++)
{
NSNumber *number = [testArray objectAtIndex:i];
for(int j = i+1; j < [testArray count]; j++)
{
NSNumber *innerLoopNumber = [testArray objectAtIndex:j];
assert(innerLoopNumber);
assert(number);
}
}
对于这些测试,我必须减少数组的大小和运行的次数,以便在合理的时间内完成它们,因为迭代次数随着O(n^2)增长而增加。 所以我跑了他们与5.000 NSNumbers数组,并重复测试5次。
结果:7.360645s 1运行
所以我想,当然,快速列举应该会更快。但要实现三角模式,以避免两次比较每个元素对,我不得不在外环与NSEnumerator在内环
for(NSNumber *number in testArray)
{
NSEnumerator *reverseEnumterator = [testArray reverseObjectEnumerator];
NSNumber *innerLoopNumber = reverseEnumterator.nextObject;
while(innerLoopNumber && ![innerLoopNumber isEqualToNumber:number])
{
innerLoopNumber = reverseEnumterator.nextObject;
assert(innerLoopNumber);
assert(number);
}
}
让我吃惊混合快速计数,这是慢得多:18。086980s 1个运行
我然后试图混合版本,以及,使用快速枚举的外环和一个for循环用于内之一:
int counter = 0;
for(NSNumber *number in testArray)
{
for(int j = counter +1; j < [testArray count]; j++)
{
NSNumber *innerLoopNumber = [testArray objectAtIndex:j];
assert(innerLoopNumber);
assert(number);
}
counter++;
}
结果:7.079600s 1运行
只比普通的for-loop稍快。
在一个地方的数字:
- 07.360645s for循环
- 07.079600s混合
- 18.086980s快速计数
所以我想,这是为什么?快速枚举只在“未中断”时才能正常工作,NSEnumerator的使用是否会干扰快速枚举? 或者我只是错过了一些东西,我的方法错了?
请注意,在'for'循环的每次迭代中,您都冗余地调用一个方法'[testArray count]'。 – echristopherson 2012-07-11 21:03:04
根据Apple的文档,当使用for-loop:“在每个循环迭代中,它会调度一条消息来获取数组中的项目数量,这是浪费的。如果数组中项目的数量永不改变,您可以分配该值的一个变量,并使用,而不是“ – user523234 2013-11-27 14:44:03