如何快速实现并行映射 [英] How to implement a parallel map in swift

查看:58
本文介绍了如何快速实现并行映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:-

extension Collection {

    // EZSE : A parralelized map for collections, operation is non blocking
    public func pmap<R>(_ each: (Self.Iterator.Element) -> R) -> [R?] {
        let indices = indicesArray()
        var res = [R?](repeating: nil, count: indices.count)

        DispatchQueue.concurrentPerform(iterations: indices.count) { (index) in
            let elementIndex = indices[index]
            res[index] = each(self[elementIndex])
        }

        // Above code is non blocking so partial exec on most runs
        return res
    }

    /// EZSE : Helper method to get an array of collection indices
    private func indicesArray() -> [Self.Index] {
        var indicesArray: [Self.Index] = []
        var nextIndex = startIndex
        while nextIndex != endIndex {
            indicesArray.append(nextIndex)
            nextIndex = index(after: nextIndex)
        }
        return indicesArray
    }
}

在这里,在return语句res处,它通常在部分执行完成后返回.有意义的是,并发Perform是非阻塞的.我不确定如何继续等待.我应该使用调度组/期望之类的方法,还是有一些更简单,更优雅的方法?本质上,我正在寻找一种快速的等待通知抽象.

In here at the return statement res, it often returns with part of the execution completed. Makes sense, concurrent Perform is non blocking. I am unsure how to proceed to wait for it. Should I use something like a dispatch group/expectations or is there some simpler more elegant method? Essentially I am looking for a simple wait notify abstraction in swift.

推荐答案

您可以尝试执行以下操作:

You can try something like this:

// EZSE : A parralelized map for collections, operation is non blocking
public func pmap<R>(_ each: @escaping (Self.Iterator.Element) -> R) -> [R] {
    let totalCount = indices.count
    var res = ContiguousArray<R?>(repeating: nil, count: totalCount)
    
    let queue = OperationQueue()
    queue.maxConcurrentOperationCount = totalCount
    
    let lock = NSRecursiveLock()
    indices
        .enumerated()
        .forEach { index, elementIndex in
            queue.addOperation {
                let temp = each(self[elementIndex])
                lock.lock()
                res[index] = temp
                lock.unlock()
            }
    }
    queue.waitUntilAllOperationsAreFinished()
    
    return res.map({ $0! })
}

这篇关于如何快速实现并行映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆