Last active
August 31, 2024 18:16
-
-
Save robertmryan/80572be8d62bf2ccb41733cf141fd0a0 to your computer and use it in GitHub Desktop.
Chunking of GCD’s concurrentPerform
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Foundation | |
| extension DispatchQueue { | |
| /// Chunked concurrentPerform | |
| /// | |
| /// - Parameters: | |
| /// | |
| /// - iterations: How many total iterations. | |
| /// | |
| /// - chunks: How many chunks into which these iterations will be divided. This is optional and will default to | |
| /// `activeProcessorCount`. If the work is largely uniform, you can safely omit this parameter and the | |
| /// work will evenly distributed amongst the CPU cores. | |
| /// | |
| /// If different chunks are likely to take significantly different amounts of time, | |
| /// you may want to increase this value above the processor count to avoid blocking the whole process | |
| /// for slowest chunk and afford the opportunity for threads processing faster chunks to handle more than one. | |
| /// | |
| /// But, be careful to not increase this value too high, as each dispatched chunk entails a modest amount of overhead. | |
| /// You may want to empirically test different chunk sizes (vs the default value) for your particular use-case. | |
| /// | |
| /// - chunk: Closure to be called for each chunk. | |
| static func chunkedConcurrentPerform(iterations: Int, chunks: Int? = nil, chunk: @Sendable (Range<Int>) -> Void) { | |
| let chunks = min(iterations, chunks ?? ProcessInfo.processInfo.activeProcessorCount) | |
| let (baseChunkSize, remainder) = iterations.quotientAndRemainder(dividingBy: chunks) | |
| concurrentPerform(iterations: chunks) { chunkIndex in | |
| let start = chunkIndex * baseChunkSize + min(chunkIndex, remainder) | |
| let end = start + baseChunkSize + (chunkIndex < remainder ? 1 : 0) | |
| chunk(start ..< end) | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment