I finally had a reason to use DispatchQueue.concurrentPerform
to spread some chunks of work across multiple cores. There’s something very satisfying about filling up CPU cores with work!
So with a bit of help from StackOverflow I came up with this Array extension for using map and for-each with a simple API.
The functions themselves are synchronous, but DispatchQueue.concurrentPerform
does its magic and runs the passed in closures across the cores.
Here’s the code. Got a suggestion? Let me know on the Gist.
Array+Concurrency.swift
public extension Array { /// Synchronous func concurrentMap(transform: @escaping (Element) -> T) -> [T] { let result = UnsafeMutablePointer .allocate(capacity: count) DispatchQueue.concurrentPerform(iterations: count) { i in result.advanced(by: i).initialize(to: transform(self[i])) } let finalResult = Array (UnsafeBufferPointer(start: result, count: count)) result.deallocate() return finalResult } /// Synchronous func concurrentForEach(action: @escaping (Element) -> Void) { _ = concurrentMap { _ = action($0) } } }
Usage
// Works just like regular `map` and `forEach`. let things = [1, 2, 3, 4] // 1 // 2 // 3 // 4 things.concurrentForEach { print($0) } let multipliedByTwo = things.concurrentMap { $0 * 2 } // [2, 4, 6, 8]