这上面有很多线程,但
Using Grand Central Dispatch in Swift to parallelize and speed up “for” loops?使用的是Swift< 3.0代码,而我无法获得相当于3的代码(参见代码).
Process Array in parallel using GCD使用指针,它有点难看,所以我要在这里断言我正在寻找漂亮的Swift 3方法来做到这一点(当然尽可能高效).我也听说团体很慢(?)也许有人可以确认.我也无法让小组工作.
这是我对跨步并行映射函数的实现(在Array的扩展中).它希望在全局队列上执行,以便不阻止UI.可能是并发位不需要在范围内,只需要余数循环.
extension Array { func parallelMap<R>(striding n: Int,f: @escaping (Element) -> R,completion: @escaping ([R]) -> ()) { let N = self.count var res = [R?](repeating: nil,count: self.count) dispatchQueue.global(qos: .userInitiated).async { dispatchQueue.concurrentPerform(iterations: N/n) {k in for i in (k * n)..<((k + 1) * n) { res[i] = f(self[i]) //Error 1 here } } //remainder loop for i in (N - (N % n))..<N { res[i] = f(self[i]) } dispatchQueue.main.sync { //But it will pause on this line. print("\nPlease work!\n") //This doesn't execute either. completion(unwrap(res)!) //Error 2 here,or rather "not here" } } } } public func unwrap<T>(_ arr: Array<T?>) -> Array<T>? { if (arr.contains{$0 == nil}) { return nil } else { return arr.map{(x: T?) -> T in x!} } }
错误1:内部数组分配线上的老朋友EXC_BAD_ACCESS大约是我测试它的一半.我猜这是一个同时访问问题.
错误2:完成永远不会执行!
最后:代码为最快的并行(确保它尽可能并行,我不喜欢我的代码中的’并发’)map / for function possible.这是修复我的代码的补充.
解决方法
马丁最初的方法仍然是正确的方法.将你的方法与他的方法合并并转换为Swift 3是相当简单的(虽然我摆脱了你的选项并且只是手工处理了内存).
extension Array { func parallelMap<R>(striding n: Int,completion: @escaping ([R]) -> ()) { let N = self.count let res = UnsafeMutablePointer<R>.allocate(capacity: N) dispatchQueue.concurrentPerform(iterations: N/n) { k in for i in (k * n)..<((k + 1) * n) { res[i] = f(self[i]) } } for i in (N - (N % n))..<N { res[i] = f(self[i]) } let finalResult = Array<R>(UnsafeBufferPointer(start: res,count: N)) res.deallocate(capacity: N) dispatchQueue.main.async { completion(finalResult) } } }
Martin的版本避免了额外的副本,因为他有一个“零”值来初始化数组.如果你知道你的类型有一个简单的init(),你可以避免额外的副本:
protocol TriviallyInitializable { init() } extension Array { func parallelMap<R>(striding n: Int,completion: @escaping ([R]) -> ()) where R: TriviallyInitializable { let N = self.count var finalResult = Array<R>(repeating: R(),count: N) finalResult.withUnsafeMutableBufferPointer { res in dispatchQueue.concurrentPerform(iterations: N/n) { k in for i in (k * n)..<((k + 1) * n) { res[i] = f(self[i]) } } } for i in (N - (N % n))..<N { finalResult[i] = f(self[i]) } dispatchQueue.main.async { completion(finalResult) } } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。