Swift DispatchQueue运行多个异步时太慢了

问题描述 投票:0回答:2

我想在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
ios swift multithreading dispatch-async
2个回答
0
投票

在你的情况下,你不应该使用 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)")
}
  • 1项任务 -> // finish: 2.910871982574463
  • 2项任务 -> // finish: 1.5314499139785767
  • 4项任务 -> // finish: 1.1279020309448242
  • 6项任务-> // finish: 0.8491430282592773
  • 8个任务-&gt。// finish: 0.7050379514694214

0
投票

在我的环境中(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在多线程中太慢了。

谢谢。

附上时间剖析器的图片

© www.soinside.com 2019 - 2024. All rights reserved.