2017-03-06 85 views
1

並行地圖我有下面的代碼: -如何實現迅速

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語句資源,它往往與執行完畢的一部分返回。有意義,併發Perform是非阻塞的。我不確定如何繼續等待它。我是否應該使用派遣組織/期望之類的東西,還是有更簡單更優雅的方法?本質上,我正在尋找一個簡單的等待通知抽象的迅速。

回答

1

你可以嘗試這樣的事情:

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

    let queue = OperationQueue() 
    let operations = indices.enumerated().map { index, elementIndex in 
     return BlockOperation { 
      res[index] = each(self[elementIndex]) 
     } 
    } 
    queue.addOperations(operations, waitUntilFinished: true) 

    return res 
} 
+0

爲什麼不返回'[R]'而不是''[R?]?我試着用'res.map({$ 0!})強制它'崩潰了,這不應該是這樣嗎? –

+0

@RodrigoRuiz,是的,可以改寫成返回'[R]'。而你遇到的崩潰:是否發生在操場上? '因爲我只能在操場上重現它,如果我添加一些隨機的額外代碼(比如'print'),甚至在操場上使用'$ 0!'在'map'之前使用本地'res'變量,它也可以。我猜這是臭名昭着的遊樂場內存管理行動。 – user28434

+0

我在單元測試中測試它。 –