我知道有相當多的話題似乎是關於完全相同的東西,但我沒有找到真正與我想要的有關的話題。快速枚舉比嵌套枚舉中的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