Suppose I have a function which provides some longtime operations.
func foo(parameter: String)
This function is synchronous and I can't change it.
I need to run the function on array of parameters:
stringArray.forEach { foo($0) }
Obviously it requires a time.
I'd prefer to make an async function to make it asynchronously, like this:
func manyFoo(parameters: [String]) async {
await withTaskGroup(of: Void.self) { group in
for parameter in parameters {
group.addTask { foo(parameter: parameters) }
}
}
}
But does it really execute foo
simultaneously?
CodePudding user response:
You ask:
But does it really execute
foo
simultaneously?
Yes it does.
Note, if you run it on the simulator, the degree of concurrency is highly constrained, so make sure to run it on a physical device. But I added some os_signpost
logging, profiled it, and watched it in Instruments’ “Points of Interest” and “Swift Tasks” tools:
You can see that on my iPhone 12 Pro Max, I am getting six concurrent tasks.
That was with:
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)
}
Note, to see any material improvement in performance, you need to make sure there is enough work on each task to justify the modest overhead that concurrency introduces. E.g., if you have a million strings and each one takes 20 milliseconds each, it might actually be slower. So you might need to do “striding” (e.g., 100 tasks, each processing 10,000 strings).
Or if your tasks are all interacting with some shared resource, like a file, you might not be able to achieve any performance improvement at all.
We cannot comment further without knowing what your synchronous task is doing.