我编写了一个使用DispatchQueue.concurrentPerform(iterations:execute :)的例程,并将其用于多线程编程中。
当我错误地将queue.sync的无意义的迭代错误放入另一个函数时,我感到惊讶,性能会更好。 通过迭代,并发性能可以在A12X Bionic中使用更多内核。
肯定Apple's document说,
许多因素会影响并发队列执行的任务数量,包括可用核心数,其他进程正在完成的工作量以及其他串行调度队列中任务的数量和优先级。
我想通过合理的方式获得更好的性能。 如何控制parallelPerform的并行性?
将队列的QoS更改为.userInitiated无效。
谢谢。
答案 0 :(得分:0)
试试吧!下一个示例以两种不同的方式执行简单作业,首先在.default .concurrent队列上异步调度所有作业,其次使用DispatchQueue.concurrentPerform。
DispatchQueue.concurrentPerform非常好,易于使用。
import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
let q = DispatchQueue(label: "internal", qos: .utility, attributes: .concurrent)
func job()->String {
var sum = 0
for i in 1...1000 {
let r = Int.random(in: 0..<i)
sum += r
}
let res = sum.description
return res
}
func asyncFoo(on: DispatchQueue, id: Int, completition: @escaping (_ id: Int, _ result: String)->()) {
on.async {
let res = job()
completition(id, res)
}
}
let group = DispatchGroup()
var start = Date()
for i in 0..<10 {
group.enter() // enter the group before the task starts
asyncFoo(on: q, id: i) { (id, result) in
print("id:", id, i, result)
group.leave() // leave the group when task finished
}
}
group.notify(queue: .main) {
var stop = Date()
print("all asynchronously dispatched done in", stop.timeIntervalSince(start), "seconds")
let task: (Int)->() = { i in
let res = job()
print("id:", i, res)
}
print("continue again ...")
start = Date()
DispatchQueue.concurrentPerform(iterations: 10, execute: task)
stop = Date()
print("all .concurrentPerform done in", stop.timeIntervalSince(start), "seconds")
PlaygroundPage.current.finishExecution()
}
print("continue execution ...")
结果如何?
continue execution ...
id: 7 7 251189
id: 2 2 252628
id: 8 8 248525
id: 5 5 248212
id: 0 0 254412
id: 3 3 255094
id: 6 6 260566
id: 1 1 242460
id: 9 9 247018
id: 4 4 246296
all asynchronously dispatched done in 0.10741996765136719 seconds
continue again ...
id: 2 248549
id: 3 245366
id: 7 242868
id: 8 252247
id: 0 250905
id: 4 249909
id: 6 247525
id: 9 246204
id: 1 253908
id: 5 249081
all .concurrentPerform done in 0.05399894714355469 seconds
如果可以的话,我更喜欢使用.concurrentPerform,但这实际上取决于...没有任何API可以更改.concurrentPerform上的任何内容,但是很可能它将是您表现最好的。