2014-02-18 38 views
0

我需要處理大量來自NSDictionary的數據到NSManagedObjects(3k-10k對象)。Objective C和線程

在同步處理中,3K花費約60秒:

for (NSString *key in myDictionary) { 
    //process data 
} 

當我使用GCD和用於每個鍵創建一個新的線程,大約需要20秒,使用一串線程:

for (NSString *key in myDictionary) { 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     //process data 
    } 
}  

然後我試圖使用NSOperationQueueNSBLockOperation和用於每個鍵,添加塊執行歷時約30秒和只用2個線程:

NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 
NSBlockOperation *operation = [[NSBlockOperation alloc] init]; 

for (NSString *key in myDictionary) { 
    [operation addExecutionBlock:^{ 
    // processs data 
    } 
} 

[operation setCompletionBlock:^{ 
    DLog(@"Block completed | time: %f", [[NSDate date] timeIntervalSinceDate:startTime]); 
}]; 

[queue addOperation:operation]; 

這給出了具有完成塊的優點。

就速度而言,每個按鍵的線程似乎是最快的。

所有時間在設備上完成,而不是模擬器。

我讀過NSOperation vs GCD,他們建議使用更高層次的API,即NSOperation,但GCD的性能更好。

使用NSOperationQueueNSBlockOperation除完成塊外還有什麼優勢嗎?或者我錯過了一些讓隊列和塊本來就比GCD更好的東西?

+0

相關:http://stackoverflow.com/questions/18632271/what-is-the-差異之間的nsinvocationoperation和nsblockoperation –

+3

在Objective-C中有大約六種不同的線程方式。除非有特別的理由選擇其中一種,否則使用你理解最好並且最舒服的技術。線程混淆不清,在複雜情況下使用不熟悉的界面只會增加混淆。 –

回答

2

或者我錯過了讓隊列和塊本身更好的GCD?

你不會錯過任何東西 - 操作是使用GCD實現的。正如你所看到的,擁有更高層次的API比直接的GCD更好,但最終操作本質上與使用GCD不同。

+0

我很好奇爲什麼操作只使用2線程,而GCD使用30+(線程ID在30年代,而不是100%肯定有30+線程)? – Padin215

+1

我不認爲使用多於一個線程。有一個線程池,所以你得到的踏板是「隨機的」。 GCD在該池的不同線程上分派塊,但AFAIK永遠不會在不同線程上執行一個塊。 (你的調度不在for循環中。)每個線程都有自己的棧,因此從一個線程移動到另一個線程將非常昂貴。 –

+0

那麼你會如何解釋GCD快10秒?我記錄[NSThread currentThread]和GCD,我看到很多線程ID,而操作只使用2個線程ID? – Padin215

1

正如前面提到的操作和操作隊列是建立在GCD之上的。但有一些區別:

  • 操作隊列可以有一個寬度。 GCD只知道串行或併發隊列。
  • 操作隊列可以處理依賴關係。
  • 操作可以有一個優先級(加)
  • GCD可以處理「運行循環的東西」(系統事件)

正如我在評論中提及您的GCD代碼只使用一個線程:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    for (NSString *key in myDictionary) { 
     //process data 
    } 
} 

試試這個並將結果報告,請:

for (NSString *key in myDictionary) { 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     //process data 
    } 
} 
+0

Bah!你是對的,我用手輸入了我的代碼,但我做錯了。我正在使用第二種方法。修正了錯誤。感謝您注意到這一點。 – Padin215

+0

所以你很清楚你有不同的線程。 ;-) –

+0

是的,這就是我打字得太快了。 = d – Padin215