Swift Array的Map方法是否同时实现?

ZH *_*LIU 1 arrays swift

检查了文档,但没有讨论实现的许多细节。想知道对于大型阵列,它是否可以并行执行?

Ale*_*ica 5

专门的map实现Array不执行任何多线程,但是没有什么可以说您无法进行并发实现。这是可以与任何对象通用的一个Sequence

import Dispatch


class SharedSynchronizedArray<T> {
    var array = [T]()
    let operationQueue = DispatchQueue(label: "SharedSynchronizedArray")

    func append(_ newElement: T) {
        operationQueue.sync {
            array.append(newElement)
        }
    }
}

public struct ConcurrentSequence<Base, Element>: Sequence
    where Base: Sequence, Element == Base.Iterator.Element {
    let base: Base

    public func makeIterator() -> Base.Iterator {
        return base.makeIterator()
    }

    public func map<T>(_ transform: @escaping (Element) -> T) -> [T] {
        let group = DispatchGroup()

        let resultsStorageQueue = DispatchQueue(label: "resultStorageQueue")
        let results = SharedSynchronizedArray<T>()

        let processingQueue = DispatchQueue(
            label: "processingQueue",
            attributes: [.concurrent]
        )

        for element in self {
            group.enter()
            print("Entered DispatchGroup for \(element)")

            var result: T?
            let workItem = DispatchWorkItem{ result = transform(element) }

            processingQueue.async(execute: workItem)

            resultsStorageQueue.async {
                workItem.wait()
                guard let unwrappedResult = result else {
                    fatalError("The work item was completed, but the result wasn't set!")
                }
                results.append(unwrappedResult) 


                group.leave()
                print("Exited DispatchGroup for \(element)")
            }
        }
        print("Started Waiting on DispatchGroup")
        group.wait()
        print("DispatchGroup done")

        return results.array
    }


}

public extension Sequence {
    public var parallel: ConcurrentSequence<Self, Iterator.Element> { 
        return ConcurrentSequence(base: self)
    }
}

print("Start")

import Foundation

let input = Array(0..<100)
let output: [Int] = input.parallel.map {
    let randomDuration = TimeInterval(Float(arc4random()) / Float(UInt32.max))
    Thread.sleep(forTimeInterval: randomDuration)
    print("Transforming \($0)")
    return $0 * 2
}

print(output)
// print(output.parallel.filter{ $0 % 3 == 0 })

print("Done")
Run Code Online (Sandbox Code Playgroud)