成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Mac OS X NSArray 枚舉性能研究

開發(fā) 項目管理 后端
一天,我在思考 NSArray 枚舉方法 (也稱迭代方法): Mac OS X 10.6 和 iOS 4 帶來了以塊(block)組成的美麗新世界,enumerateObjectsUsingBlock: 方法隨之而來。

一天,我在思考 NSArray 枚舉方法 (也稱迭代方法): Mac OS X 10.6 和 iOS 4 帶來了以塊(block)組成的美麗新世界,enumerateObjectsUsingBlock: 方法隨之而來。我感覺這個方法要慢于快速枚舉 (for (object in array) { ... }),因為有總體開銷,但我并不能確定。因此我決定做一次性能測評。

都有哪些枚舉方法?

總體來說,我們有4種可以使用的枚舉方法 (參考 Mike Ash 的 周五常見問題 2010-04-09: Objective-C 的枚舉方法對比)。

1、objectAtIndex: enumeration 使用一個 for 循環(huán),遞增循環(huán)變量,然后用 [myArray objectAtIndex:index] 來訪問元素。這是最基本的枚舉形式。

  1. NSUInteger count = [myArray count];  
  2. for (NSUInteger index = 0; index < count ; index++) {  
  3.     [self doSomethingWith:[myArray objectAtIndex:index]];  
  4. }  

2、NSEnumerator 外部迭代(external iteration)的形式: [myArray objectEnumerator] 返回一個對象,這個對象有  nextObject 方法。我們可以循環(huán)調用這個方法,直到返回 nil 為止。

  1. NSEnumerator *enumerator = [myArray objectEnumerator];  
  2. id object;  
  3. while (object = [enumerator nextObject]) {  
  4.     [self doSomethingWith:object];  
  5. }  

3、NSFastEnumerator The idea behind 快速枚舉 的思想是利用 C 數(shù)組快速訪問 來優(yōu)化迭代。不僅它理論上比傳統(tǒng)的  NSEnumerator 更快,而且 Objective-C 2.0 提供了這種簡明的語法:

  1. id object;  
  2. for (object in myArray) {  
  3.     [self doSomethingWith:object];  

4、Block enumeration(塊枚舉)引入 blocks 后出現(xiàn)的方法,它可以基于塊來迭代訪問一個數(shù)組。它的語法沒有快速枚舉那么簡潔,但它有一個有趣的特性: 并發(fā)枚舉。如果枚舉的順序并不重要,而且實施的處理可以并發(fā)進行,不用鎖,這種方法可以在多核系統(tǒng)上帶來相當明顯的效率提升。詳情參考 并發(fā)枚舉一節(jié)

  1. [myArray enumerateObjectsUsingBlock:^(id object, NSUInteger index, BOOL *stop) {  
  2.     [self doSomethingWith:object];  
  3. }];  
  4. [myArray enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {  
  5.     [self doSomethingWith:object];  
  6. }]; 

線性枚舉

首先,我們討論一下線性枚舉:一個項目接著前一個。

圖表

 

結論

有一點令人驚訝的是,NSEnumerator甚至比使用objectAtIndex:還慢。這對于Mac OS X 和IOS是一個事實。我猜想這是由于枚舉器在每次迭代時都去檢查數(shù)組是否被修改。自然地,快速枚舉保存了每個原始的名字,因此是最快的解決方案。

對于小的數(shù)組,block enumeration 比objectAtIndex:稍慢一點,但在有大量元素的數(shù)組里,它的性能變得與fast enumeration差不多快。

fast enumeration和NSEnumeration之間的區(qū)別在很多地方已經(jīng)非常明顯:對于iPhone 4S,前者花費約0.037秒而后者需要0.140秒。這已經(jīng)相差了3.7陪。

奇怪的一點

***在程序中分配 NSArray 和***用objectEnumerator 獲取 enumerator 都需要異常長的時間才能完成。例如,在我 2007 年的 17 寸 MacBook Pro 上分配含一個元素的數(shù)組,所需時間的中位數(shù)是 415 納秒。但***分配的時候會需要 500,000 納秒,有時甚至要到 1,000,000 納秒!獲取 enumerator 也是如此:盡管中位數(shù)只有 673 納秒,***獲取卻要花 500,000 納秒以上。

我只能猜測其中的原因,但我懷疑延遲加載是罪魁禍首。在實際應用中,你可能不會注意到這一點,因為等到執(zhí)行你的代碼時,Cocoa 或 Cocoa Touch 很可能已經(jīng)創(chuàng)建過數(shù)組了。

并發(fā)枚舉

如果情況允許,你可以選擇用塊枚舉來并發(fā)枚舉對象。這意味著計算的工作量可以分散到幾個 CPU 內核上。并不是每種枚舉過程中的處理都是可并發(fā)的,因此只有沒用到鎖的時候,才能使用并發(fā)枚舉:要么每一步操作確實是絕對相互獨立的,要么有原子性的操作可用 (如 OSAtomicAdd32 之類)。

那么,它相比其他枚舉類型有多大優(yōu)勢呢?

圖表

 

結論

元素不多時,并發(fā)枚舉是目前最慢的方法。主要原因可能是為了讓數(shù)組能并發(fā)訪問而做的準備工作和開啟線程(我不知道用的是 GCD 還是“傳統(tǒng)的”線程,這不重要;這是我們不需關心的實現(xiàn)細節(jié))。

盡管如此,如果數(shù)組足夠大,并發(fā)枚舉突然就成了最快的方法了,正如我們所料。在 iPhone 4S 上枚舉 100 萬個元素,用并發(fā)枚舉需要 0.024 秒,但快速枚舉需要 0.036 秒。相形之下,還是同一個數(shù)組,NSEnumeration 要用 0.139 秒! 這已經(jīng)是非常大的差距了,足有 5.7 倍之多。

在我的辦公室,2011 iMac 24"采用了酷睿i7四核CPU,同時在0.0016秒之內列舉了百萬項。同一數(shù)組快速枚舉了0.0044秒和NSEnumeration o.oo93秒。那個因數(shù)是5.8,它非常接近于ipone 4S的結果。在這里,我期待一個更大的差異,雖然,在我的2007 MacBook采用了Core2 Duo雙核CPU,在這里因數(shù)剛好是3.7.當同時枚舉的閾值成為有用,在某處以我的測試是10,000和50,000分子之間。用更少的分子元素,去掉正常的塊迭代。

#p#

分配方式

我也想知道枚舉的性能會不會受數(shù)組創(chuàng)建方式的影響。我測試了兩個不同的方法:

  1. 首先創(chuàng)建一個 C 數(shù)組,里面引用了數(shù)組元素的對象實例,然后再用 initWithObjects:count: 創(chuàng)建NSArray。

  2. 直接創(chuàng)建 NSMutableArray 并依次用 addObject: 添加對象。

結果是迭代過程的沒有區(qū)別,但分配過程有所不同:initWithObjects:count: 快一些。數(shù)組元素很多時,差距更加顯著。這個例子創(chuàng)建了一個元素為 NSNumber 的數(shù)組:

  1. NSArray *generateArrayMalloc(NSUInteger numEntries) {  
  2.     id *entries;  
  3.     NSArray *result;  
  4.           
  5.     entries = malloc(sizeof(id) * numEntries);  
  6.     for (NSUInteger i = 0; i < numEntries; i++) {  
  7.         entries[i] = [NSNumber numberWithUnsignedInt:i];  
  8.     }  
  9.       
  10.     result = [NSArray arrayWithObjects:entries count:numEntries];  
  11.       
  12.     free(entries);  
  13.     return result;  

 

我是如何來測量的?

你可以從 http://darkdust.net/files/arraytest.m 來下載這個測試應用 看看我是如何來測量的。基本上我就是測量重復迭代一個數(shù)組(什么處理也不做)1000次需要多長時間。在圖表中,取每個數(shù)組尺寸的平均值。這個應用的編譯選項是關閉優(yōu)化(-O0)。對于 iOS,我是在一個 iPhone 4S 上進行的測試。對 MAC OS X,我用我家里2007年產(chǎn)的 MacBook Pro 17”和我辦公室2011年產(chǎn)的 iMac 24”來測試。MAC OS X的圖表顯示的是iMac上的結果,在MacBook Pro上的圖表看起來與此相似,只是更慢一些。

英文原文:NSArray enumeration performance examined

原文鏈接:http://www.oschina.net/translate/nsarray-enumeration-performance

責任編輯:林師授 來源: 開源中國社區(qū) 編譯
相關推薦

2012-02-17 09:21:22

Mac OS X

2009-09-01 12:59:06

雪豹蘋果操作系統(tǒng)

2012-02-17 14:41:12

Mac OS XOS XiOS

2012-02-02 10:30:30

Mac OS X 10正式發(fā)布

2011-07-22 09:06:01

Mac OS X Li

2013-06-07 14:35:19

Mac OS X

2011-10-20 20:56:42

UbuntuMac OS X

2010-01-11 09:58:33

谷歌蘋果Chrome OS

2011-11-16 09:47:54

2014-12-24 09:11:53

Mac OS X Se

2013-02-26 09:14:52

2011-06-21 11:04:55

Linus TorvaMac OS X

2009-03-23 09:57:19

2011-07-08 09:23:45

Mac OS X Li

2012-11-13 10:47:00

Mac OS X

2011-08-11 13:59:53

Mac OS X

2009-05-14 17:31:20

Ubuntu 9.04Mac OS X 10

2016-12-13 10:22:54

Mac OS X顯示服務

2011-09-28 10:12:06

Mac OS X

2014-06-03 16:59:22

OS XOS X Yosemi
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩 欧美 综合 | 精品久久久久久久久久久久 | 91在线导航 | 在线播放中文 | 亚洲精品久久久久中文字幕二区 | www久久| 91超碰在线 | 日本人做爰大片免费观看一老师 | 亚洲精品456 | 国产日韩电影 | 日韩精品视频网 | 91在线导航| 国产精品欧美精品 | 91视频一区| 欧美视频免费在线 | 成年视频在线观看 | 69性欧美高清影院 | 国产一区二区精品在线观看 | 精品久久久久久红码专区 | 狠狠躁躁夜夜躁波多野结依 | 欧美久久一区二区三区 | 日韩区| 亚洲一区二区三区在线 | 久久6视频| 懂色av色香蕉一区二区蜜桃 | 久草热在线 | av免费网站在线 | 这里只有精品999 | 成人网av| 一级毛片视频 | 玖玖操 | 青青草综合网 | 97人人草 | 91精品成人久久 | 精品一区二区三区四区 | 羞羞视频一区二区 | 国产一区二区三区在线视频 | 国产91丝袜在线播放 | 日韩精品无码一区二区三区 | 亚洲精品4 | 欧美日韩国产一区二区三区 |