併發迴圈

GCD 提供了執行迴圈的機制,其中迴圈相互之間同時發生。這在執行一系列計算上昂貴的計算時非常有用。

考慮這個迴圈:

for index in 0 ..< iterations {
    // Do something computationally expensive here
}

你可以使用 concurrentPerform(在 Swift 3 中)或 dispatch_apply(在 Swift 2 中)同時執行這些計算:

Version = 3.0

DispatchQueue.concurrentPerform(iterations: iterations) { index in
    // Do something computationally expensive here
}

Version < 3.0

dispatch_apply(iterations, queue) { index in
    // Do something computationally expensive here
}

對於每個 index,將從 0 呼叫迴圈閉包,但不包括 iterations。這些迭代將相互併發執行,因此不能保證它們執行的​​順序。在任何給定時間同時發生的實際迭代次數通常由所討論的裝置的能力決定(例如,裝置具有多少個核心)。

一些特殊注意事項:

  • concurrentPerform / dispatch_apply 可以相互之間同時執行迴圈,但這一切都與你呼叫它的執行緒同步發生。所以,不要從主執行緒呼叫它,因為這將阻塞該執行緒,直到迴圈完成。

  • 因為這些迴圈彼此同時發生,所以你有責任確保結果的執行緒安全性。例如,如果使用這些計算上昂貴的計算結果更新某些字典,請確保自己同步這些更新。

  • 注意,執行併發迴圈時會產生一些開銷。因此,如果在迴圈內執行的計算計算量不夠大,你可能會發現通過使用併發迴圈獲得的任何效能可能會因與同步所有這些併發執行緒相關的開銷而減少(如果沒有完全抵消)。

    因此,你有責任確定在迴圈的每次迭代中要執行的正確工作量。如果計算過於簡單,你可以使用跨越來為每個迴圈包含更多工作。例如,你可以在迴圈中執行 100 次迭代,而不是執行 100 萬次平凡計算的併發迴圈,每次迴圈執行 10,000 次計算。這樣就可以在每個執行緒上執行足夠的工作,因此與管理這些併發迴圈相關的開銷變得不那麼重要了。