swift 具有同步功能的任务组

brc7rcf0  于 2022-10-31  发布在  Swift
关注(0)|答案(1)|浏览(173)

假设我有一个函数,它提供一些长时间的操作。

func foo(parameter: String)

这个函数是同步的,我不能改变它。
我需要对参数数组运行函数:

stringArray.forEach { foo($0) }

显然这需要时间。
我更喜欢创建一个async函数来使其异步,如下所示:

func manyFoo(parameters: [String]) async {
    await withTaskGroup(of: Void.self) { group in
        for parameter in parameters {
            group.addTask { foo(parameter: parameters) }
        }
    } 
}

但是它真的同时执行foo吗?

lfapxunr

lfapxunr1#

你问:
但是它真的同时执行foo吗?
是的,的确如此。
注意,如果在模拟器上运行,并发程度会受到很大限制,因此请确保在物理设备上运行它。但我添加了一些os_signpost日志记录,对其进行了分析,并在Instruments的“Points of Interest”和“Swift Tasks”工具中观看了它:

你可以看到在我的iPhone 12 Pro Max上,我得到了六个并发任务。
电光石火间:

import os.log

private let log = OSLog(subsystem: "Test", category: .pointsOfInterest)

func foo(parameter: String) {
    let id = OSSignpostID(log: log)
    os_signpost(.begin, log: log, name: #function, signpostID: id, "%@: OK")

    ...

    os_signpost(.end, log: log, name: #function, signpostID: id)
}

注意,要想看到性能的实质性提升,你需要确保每个任务都有足够的工作量来证明并发所带来的适度开销是合理的。例如,如果你有一百万个字符串,每个字符串需要20毫秒,实际上可能会更慢。所以你可能需要做“大步走”(striding)(例如,100个任务,每个任务处理10,000个字符串)。
或者,如果您的任务都与某个共享资源(如文件)进行交互,则可能根本无法实现任何性能改进。
在不知道您的同步任务正在执行什么操作的情况下,我们无法进行进一步的评论。

相关问题