let dispatchGroup = dispatch_group_create()
let now = DISPATCH_TIME_NOW
for i in 0..<1000 {
dispatch_group_enter(dispatchGroup)
// Do some async tasks
let delay = dispatch_time(now, Int64(Double(i) * 0.1 * Double(NSEC_PER_SEC)))
dispatch_after(delay, dispatch_get_main_queue(), {
print(i)
dispatch_group_leave(dispatchGroup)
})
}
print语句可以顺利地打印前15-20个数字,但是,当i
变大时,print语句打印的东西很慢。我在dispatch_after
内部有更复杂的逻辑,我注意到处理非常慢,这就是我写这个测试的原因。
是否有缓冲区大小或其他属性可以配置?似乎dispatch_get_main_queue()
不能很好地处理大量的异步任务。
提前感谢!
1条答案
按热度按时间ohtdti5x1#
问题不在于
dispatch_get_main_queue()
。(如果使用不同的队列,您将注意到相同的行为。)问题在于dispatch_after()
。当你使用
dispatch_after
时,它会创建一个调度计时器,其误差为start
/when
的10%。(start
± 10%leeway
)重叠时,它可能会开始合并它们。当它们合并时,它们会看起来像是以“聚集”的方式发射,一群人紧接着另一群人开火,然后在到达下一群人之前有一点延迟。有两种解决方案,所有这些解决方案都需要淘汰
dispatch_after
调用系列:1.您可以手动构建计时器,强制
DispatchSource.TimerFlag.strict
禁用合并:就我个人而言,我不喜欢闭包中对
timer
的引用,但是您需要保留一些对它的强引用,直到计时器触发,并且当计时器取消/完成时,GCD计时器释放块(避免强引用循环)。恕我直言,这是一个不优雅的解决方案。1.更有效的方法是仅调度每0.1秒触发一次的单个重复计时器:
这不仅解决了聚结问题,而且效率更高。
有关Swift 2.3格式副本,请参阅previous version of this answer。