GCD提供了执行循环的机制,从而使循环相对于彼此同时发生。当执行一系列计算量大的计算时,这非常有用。
考虑以下循环:
for index in 0 ..< iterations { // 在这里做一些计算昂贵的事情 }
您可以使用concurrentPerform(在Swift 3中)或dispatch_apply(在Swift 2中)同时执行这些计算:
DispatchQueue.concurrentPerform(iterations: iterations) { index in // 在这里做一些计算昂贵的事情 }
dispatch_apply(iterations, queue) { index in // 在这里做一些计算昂贵的事情 }
该环路闭合将被调用每个index从0到,但不包括iterations。这些迭代将相对于彼此并发运行,因此不能保证它们的运行顺序。在任何给定时间同时发生的实际迭代次数通常取决于所讨论设备的功能(例如,设备具有多少个内核)。
有两个特殊注意事项:
该concurrentPerform/dispatch_apply可相对于彼此同时运行的循环,而这一切对于您从中调用它的线程同步发生。因此,请勿从主线程调用此方法,因为这将阻塞该线程,直到完成循环为止。
因为这些循环是相对于彼此同时发生的,所以您有责任确保结果的线程安全性。例如,如果使用这些计算量大的计算结果来更新某些词典,请确保自己同步这些更新。
请注意,运行并发循环会产生一些开销。因此,如果在循环内执行的计算的计算量不足,您可能会发现,与同步所有这些并发线程相关的开销可能会降低(即使不能完全抵消)使用并发循环获得的任何性能。
因此,您有责任确定在循环的每次迭代中要执行的正确工作量。如果计算太简单,则可以使用“跨步”来在每个循环中包含更多的工作。例如,您可以在循环中执行100次迭代,而不是对一百万个琐碎的计算执行并发循环,每个循环进行10,000次计算。这样,每个线程上执行的工作量就很多,因此与管理这些并发循环相关的开销变得不那么重要了。