我想在Swift中运行一个重任务。
所以我尝试使用DispatchQueue并并发运行它,但当我使用多个async()时,它变得太慢了。
但是当我使用多个async()时,它变得太慢了。
在这个例子中,当把'tasks'变量变大的时候,总的经过时间就会变长。
在Time Profiler中,似乎在运行并发。
我想Swift可能会自动插入一些同步代码。
我必须用Objective-C或C++来写重任务吗?
import SwiftUI
struct ContentView: View {
@State var isEnabled = false
private func calculateSomething(taskCount: Int) {
print("start")
let start = Date()
var c : Int64 = 0
for _ in 0..<1000000/taskCount {
c += Int64.random(in: 0..<2)
}
let elapsed = Date().timeIntervalSince(start)
print("end \(c) \(elapsed)")
}
private func execute() {
let group = DispatchGroup()
let queue = DispatchQueue(label: "test", qos: .userInitiated, attributes: .concurrent)
let start = Date()
let tasks = 1 // change here
for _ in 0..<tasks {
queue.async(group: group) {
self.calculateSomething(taskCount: tasks)
}
}
group.notify(queue: DispatchQueue.main) {
let elapsed = Date().timeIntervalSince(start)
print("finish: \(elapsed)")
self.isEnabled.toggle()
}
}
var body: some View {
Button("Tap Me") {
self.execute()
}
.foregroundColor(.white)
.padding()
.background(isEnabled ? Color.green : Color.gray)
.animation(.default)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
当'tasks'为1时。
start
end 500115 0.3357279300689697
finish: 0.3377569913864136
当'tasks'为5时
start
start
start
start
start
end 99749 1.4837110042572021
end 100203 1.5053819417953491
end 100083 1.5215749740600586
end 100421 1.5263309478759766
end 99923 1.5273290872573853
finish: 1.5298069715499878
在你的情况下,你不应该使用 DispatchQueue
. 如果你要做一些并发的事情,那么最好使用 OperationQueue
func calculateSomething(taskCount: Int) {
print("start")
let start = Date()
var c : Int64 = 0
for _ in 0 ..< (100000/taskCount) {
c += Int64.random(in: 0..<2)
}
let elapsed = Date().timeIntervalSince(start)
print("end \(c) \(elapsed)")
}
let taskCount = 4
let start = Date()
let operationQueue = OperationQueue()
operationQueue.name = "test"
operationQueue.qualityOfService = .userInitiated
operationQueue.maxConcurrentOperationCount = 20
operationQueue.addOperations((0 ..< taskCount).map { _ in BlockOperation {
calculateSomething(taskCount: taskCount)
}}, waitUntilFinished: true)
operationQueue.addBarrierBlock {
let elapsed = Date().timeIntervalSince(start)
print("finish: \(elapsed)")
}
// finish: 2.910871982574463
// finish: 1.5314499139785767
// finish: 1.1279020309448242
// finish: 0.8491430282592773
// finish: 0.7050379514694214
在我的环境中(iPhone XS(6核)),Debug构建时,2比1快,而在Release构建时,1比1快......这很奇怪。
Debug Build (-Onone)
1 tasks -> finish: 0.9507900476455688
2 tasks -> finish: 0.6010699272155762
3 tasks -> finish: 1.5799440145492554
4 tasks -> finish: 1.8217450380325317
5 tasks -> finish: 1.9221049547195435
Release Build (-O)
1 tasks -> finish: 0.3371950387954712
2 tasks -> finish: 0.5009279251098633
3 tasks -> finish: 0.6799429655075073
4 tasks -> finish: 1.1044269800186157
5 tasks -> finish: 1.315310001373291
我注意到,如果taskCount是2或以上,lockunlock会消耗大量的时间,RandomNumberGenerator在多线程中太慢了。
谢谢。