ios – 使用dispatch_async在Swift中同时分析数组

ios – 使用dispatch_async在Swift中同时分析数组,第1张

概述我正在尝试使用GCD的后台线程同时分析照片.这是我写的代码: dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_UTILITY.value), 0)) { for (var i = 0; i < 8; i++) { let color = self.photoAnalyzer.analyzeColors(i 我正在尝试使用GCD的后台线程同时分析照片.这是我写的代码:

dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_UTIliTY.value),0)) {    for (var i = 0; i < 8; i++)    {        let color = self.photoAnalyzer.analyzecolors(imageStrips[i])        color@R_@R_403_6939@[email protected](color)    }}

有关变量名称的说明,以下是它们的描述:

photoAnalyzer是我编写的一个名为Analyzer的类的实例,它包含处理图像的所有方法.

analyzecolors是Analyzer类中的一个方法,它执行大部分分析并返回一个字符串,其中包含传入图像的主色

imageStrips是UIImage的一个数组,构成了原始图像的各个部分

color@R_@R_403_6939@_6818@是一个字符串数组,用于存储analyzecolor方法的每个部分的返回值.

上面的代码顺序运行,因为for循环一次只访问image@R_@R_403_6939@_6818@中的一个图像.我想要做的是同时分析imageStrips中的每个图像,但我不知道如何去做.

任何建议将不胜感激.如果您希望看到所有代码以进一步帮助我,我可以发布一个GitHub链接.

编辑这是我同时处理8个处理器的更新代码.

dispatch_apply(8,imageQueue) { numStrips -> VoID in    let color = self.photoAnalyzer.analyzecolors(imageStrips[numStrips])    color@R_@R_403_6939@[email protected](color)}

但是,如果我尝试使用超过8个代码实际上运行速度比顺序运行慢.

解决方法 有几种方法可以做到这一点,但在我们开始之前有几点意见:

>要尝试最大限度地提高性能,如果您进行任何并发处理,请注意不保证它们的完成顺序.因此,如果它们出现的顺序很重要,那么简单的color@R_@R_403_6939@[email protected](颜色)模式将不起作用.您可以预先填充color@R_@R_403_6939@_6818@,然后让每个迭代只执行color@R_@R_403_6939@_6818@ [i] = color,也可以使用字典. (显然,如果订单不重要,那么这并不重要.)
>因为这些迭代将同时运行,所以您需要同步color@R_@R_403_6939@_6818@的更新.那么在后台队列上同时执行昂贵的analyzecolors,但是使用串行队列来更新color@R_@R_403_6939@_6818@,以确保没有多个更新相互跨越.
>在进行并发处理时,会有收益递减的点.例如,执行复杂的任务并将其分解为2-4个并发循环可能会产生一些性能优势,但如果您开始增加并发线程数太多,您会发现这些线程的开销会对性能产生负面影响.因此,使用不同程度的并发性对此进行基准测试,并且不要认为“更多线程”总是更好.

就如何实现这一点而言,有两种基本技术:

>如果在“并发编程指南:调度队列”指南中看到Performing Loop Iterations Concurrently,他们会讨论dispatch_apply,它是为此目的精确设计的,可以同时运行循环.

color@R_@R_403_6939@_6818@ = [Int](count: 8,repeatedValue: 0)  // I don't kNow what type this `color@R_@R_403_6939@_6818@` array is,so initialize this with whatever type makes sense for your applet queue = dispatch_get_global_queue(QOS_CLASS_UTIliTY,0)let qos_attr = dispatch_queue_attr_make_with_qos_class(disPATCH_QUEUE_SERIAL,QOS_CLASS_UTIliTY,0)let syncQueue = dispatch_queue_create("com.domain.app.sync",qos_attr)dispatch_apply(8,queue) { iteration in    let color = self.photoAnalyzer.analyzecolors(imageStrips[iteration])    dispatch_sync(syncQueue) {        color@R_@R_403_6939@_6818@[iteration] = color        return    }}// you can use `color@R_@R_403_6939@_6818@` here

请注意,虽然这些迭代并发运行,但整个dispatch_apply循环与您启动它的队列同步运行.这意味着您不希望从主线程调用上面的代码(我们永远不想阻止主线程).所以很可能想把这整件事发送到一些后台队列.

顺便说一下,在WWDC 2011视频Blocks and Grand Central Dispatch in Practice中讨论了dispatch_apply.
>另一种常见模式是创建调度组,使用该组将任务分派到并发队列,并指定dispatch_group_notify以指定完成后要执行的 *** 作.

color@R_@R_403_6939@_6818@ = [Int](count: 8,so initialize this with whatever type makes sense for your applet group = dispatch_group_create()let queue = dispatch_get_global_queue(QOS_CLASS_UTIliTY,qos_attr)for i in 0 ..< 8 {    dispatch_group_async(group,queue) {        let color = self.photoAnalyzer.analyzecolors(imageStrips[i])        dispatch_sync(syncQueue) {            color@R_@R_403_6939@_6818@[i] = color            return        }    }}dispatch_group_notify(group,dispatch_get_main_queue()) {    // use `color@R_@R_403_6939@_6818@` here}// but not here (because the above code is running asynchronously)

这种方法可以避免完全阻塞主线程,但是必须小心不要添加太多的并发调度任务(因为工作线程是非常有限的资源).

在这两个示例中,我创建了一个专用的串行队列,用于将更新同步到color@R_@R_403_6939@_6818@.这可能有点矫枉过正.如果您没有阻塞主队列(无论如何都不应该这样做),您可以将此同步代码分派给主队列(这是一个串行队列).但是为此目的拥有一个专用的串行队列可能更精确.如果这是我将不断与多个线程进行交互的东西,我将使用读写器模式.但这对于这种情况来说可能已经足够了.

总结

以上是内存溢出为你收集整理的ios – 使用dispatch_async在Swift中同时分析数组全部内容,希望文章能够帮你解决ios – 使用dispatch_async在Swift中同时分析数组所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1045176.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存