h$: Noneconduit-concurrent-map 3concurrentMapM_ numThreads workerOutputBufferSize f6Concurrent, order-preserving conduit mapping function.Like , but runs in parallel with the given number of threads, returns outputs in the order of inputs (like mapM, no reordering), and allows defining a bounded size output buffer for elements of type b= to maintain high parallelism despite head-of-line blocking.Because of the no-reordering guarantee, there is head-of-line blocking: When the conduit has to process a long-running computation and a short-running computation in parallel, the result of short one cannot be yielded before the long one is done. Unless we buffer the queued result somewhere, the thread that finished the short-running computation is now blocked and sits idle (low utilisation).4To cope with this, this function gives each thread workerOutputBufferSize output slots to store bs while they are blocked.Use the convenience  when f is CPU-bound.workerOutputBufferSize must be given >= 1.The workerOutputBufferSize; keeps the memory usage of the conduit bounded, namely to )numThreads * (workerOutputBufferSize + 1) many bs at any given time (the + 1' is for the currently processing ones).?To achieve maximum parallelism/utilisation, you should choose workerOutputBufferSize= ideally as the time factor between the fastest and slowest f that will likely pass through the conduit; for example, if most f4s take 3 seconds, but some take 15 seconds, choose workerOutputBufferSize = 5 to avoid an earlier 15-second f blocking a later 3-second f.The threads inside the conduit will evaluate the results of the f to WHNF, as in  !b <- f a, so don't forget to make f itself deepseq the result if there is any lazy data structure involved and you want to make sure that they are evaluated *inside* the conduit (fully in parallel) as opposed to the lazy parts of them being evaluated after being yielded.As fs happen concurrently, they cannot depend on each other's monadic state. This is enforced by the ? constraint. This means the function cannot be used with e.g. StateT. Properties:2Ordering / head of line blocking for outputs: The b String -> m () -- for non-interleaved output puts s = liftIO $ BS8.putStrLn (BS8.pack s) runConduitRes (CL.sourceList [1..6] .| concurrentMapM_ 4 (\i -> liftIO $ puts (show i ++ " before") >> threadDelay (i * 1000000) >> puts (show i ++ " after") >> return (i*2)) .| CL.consume )conduit-concurrent-map# with the number of threads set to . Useful when f is CPU-bound.If f' is IO-bound, you probably want to use 2 with explicitly given amount of threads instead. 3conduit-concurrent-map-0.1.3-KqPWCc3udDK4g9mQLJgR6iData.Conduit.ConcurrentMap Data.ConduitmapMconcurrentMapM_concurrentMapM_numCaps,unliftio-core-0.2.0.1-9GVcmaajsglG88oErAZOTVControl.Monad.IO.Unlift MonadUnliftIO&conduit-1.3.4.2-7EZCvB5VsZ7KhbiwwFmNfTData.Conduit.Internal.Conduitawaitbase GHC.Conc.SyncgetNumCapabilities