on Sun Oct 30 2016, Dave Abrahams <swift-users-AT-swift.org> wrote: >> I quite like the API as an extension on Range. I think it would be a >> nice addition to Dispatch (once we start allowing additive proposals): >> >> extension Range where Bound : Strideable, Bound.Stride : SignedInteger { >> >> func concurrentMap<T>(_ transform: (Bound) -> T) -> [T] { >> let n = numericCast(count) as Int >> let buffer = UnsafeMutablePointer<T>.allocate(capacity: n) >> >> DispatchQueue.concurrentPerform(iterations: n) { >> (buffer + $0).initialize(to: transform(lowerBound + numericCast($0))) >> } >> >> // Unfortunately, the buffer is copied when making it an Array<T>. >> defer { buffer.deallocate(capacity: n) } >> return Array(UnsafeMutableBufferPointer<T>(start: buffer, count: n)) >> } >> } >> >> extension Collection { >> func concurrentMap<T>(_ transform: (Iterator.Element)->T) -> [T] { >> >> // ‘as Range’ because CountableRange is a collection, causing the >> function to be recursive. >> return ((0..<numericCast(count)) as Range).concurrentMap { >> transform(self[index(startIndex, offsetBy: numericCast($0))]) >> } >> } >> } > > I see the beauty in what you're doing here, but I don't see any > advantage to it for users. Now Range (which will be collapsed with > CountableRange in Swift 4) will have two overloads of concurrentMap. In > general, avoidable overloads are bad for the user experience.
Oh, and I should add, a suite of parallel algorithms would be great, but it should be implemented similarly to lazy, so instead of x.concurrentMap { ... }.concurrentFilter { ... } you'd write x.parallel.map { ... }.filter { ... } Cheers, -- -Dave _______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users