@@ -88,18 +88,54 @@ inspect $ 'roundRobin2 `hasNoType` ''SPEC
8888inspect $ 'roundRobin2 `hasNoType` ''D.InterleaveState
8989#endif
9090
91−o_1_space_joining :: Int -> [Benchmark]
92−o_1_space_joining value =
93− [ bgroup "joining"
94− [ benchIOSrc1 "wSerial (2,x/2)" (wSerial2 value)
95− , benchIOSrc1 "interleave (2,x/2)" (interleave2 value)
96− , benchIOSrc1 "roundRobin (2,x/2)" (roundRobin2 value)
97− ]
98− ]
91+{-# INLINE sourceUnfoldrMUF #-}
92+-- (count, value)
93+sourceUnfoldrMUF :: Monad m => Int -> UF.Unfold m (Int, Int) Int
94+sourceUnfoldrMUF count = UF.unfoldrM step
95+ where
96+ step (cnt, start) =
97+ return $
98+ if cnt > start + count
99+ then Nothing
100+ else Just (cnt, (cnt + 1, start))
101+
102+{-# INLINE unfoldManyInterleave #-}
103+unfoldManyInterleave :: Int -> Int -> Int -> IO ()
104+unfoldManyInterleave outer inner n =
105+ S.drain $ Internal.unfoldManyInterleave
106+ -- (UF.lmap return (UF.replicateM inner))
107+ (UF.lmap (\x -> (x,x)) (sourceUnfoldrMUF inner))
108+ (sourceUnfoldrM outer n)
99109
100−-------------------------------------------------------------------------------
101−-- Concat
102−-------------------------------------------------------------------------------
110+#ifdef INSPECTION
111+inspect $ hasNoTypeClasses 'unfoldManyInterleave
112+-- inspect $ 'unfoldManyInterleave `hasNoType` ''SPEC
113+-- inspect $ 'unfoldManyInterleave `hasNoType`
114+-- ''D.ConcatUnfoldInterleaveState
115+#endif
116+
117+{-# INLINE unfoldManyRoundRobin #-}
118+unfoldManyRoundRobin :: Int -> Int -> Int -> IO ()
119+unfoldManyRoundRobin outer inner n =
120+ S.drain $ Internal.unfoldManyRoundRobin
121+ -- (UF.lmap return (UF.replicateM inner))
122+ (UF.lmap (\x -> (x,x)) (sourceUnfoldrMUF inner))
123+ (sourceUnfoldrM outer n)
124+
125+#ifdef INSPECTION
126+inspect $ hasNoTypeClasses 'unfoldManyRoundRobin
127+-- inspect $ 'unfoldManyRoundRobin `hasNoType` ''SPEC
128+-- inspect $ 'unfoldManyRoundRobin `hasNoType`
129+-- ''D.ConcatUnfoldInterleaveState
130+#endif
131+
132+{-# INLINE concatPairsWithWSerial #-}
133+concatPairsWithWSerial :: Int -> Int -> Int -> IO ()
134+concatPairsWithWSerial = concatPairsWith Internal.wSerial
135+
136+{-# INLINE concatPairsWithRoundrobin #-}
137+concatPairsWithRoundrobin :: Int -> Int -> Int -> IO ()
138+concatPairsWithRoundrobin = concatPairsWith Internal.roundrobin
103139
104140{-# INLINE concatMapWithWSerial #-}
105141concatMapWithWSerial :: Int -> Int -> Int -> IO ()
@@ -110,86 +146,189 @@ inspect $ hasNoTypeClasses 'concatMapWithWSerial
110146inspect $ 'concatMapWithWSerial `hasNoType` ''SPEC
111147#endif
112148
149+o_1_space_joining :: Int -> [Benchmark]
150+o_1_space_joining value =
151+ [ bgroup "joining (2 of n/2)"
152+ [ benchIOSrc1 "wSerial" (wSerial2 value)
153+ , benchIOSrc1 "interleave" (interleave2 value)
154+ , benchIOSrc1 "roundRobin" (roundRobin2 value)
155+ , benchIOSrc1
156+ "concatMapWithWSerial"
157+ (concatMapWithWSerial 2 (value `div` 2))
158+ , benchIOSrc1
159+ "concatMapWithInterleave"
160+ (concatStreamsWith Internal.interleave 2 (value `div` 2))
161+ , benchIOSrc1
162+ "concatMapWithRoundrobin"
163+ (concatStreamsWith Internal.roundrobin 2 (value `div` 2))
164+ , benchIOSrc1
165+ "unfoldManyInterleave"
166+ (unfoldManyInterleave 2 (value `div` 2))
167+ , benchIOSrc1
168+ "concatPairsWithWSerial"
169+ (concatPairsWithWSerial 2 (value `div` 2))
170+ , benchIOSrc1
171+ "concatPairsWithRoundrobin"
172+ (concatPairsWithRoundrobin 2 (value `div` 2))
173+ ]
174+ ]
175+
176+-------------------------------------------------------------------------------
177+-- Concat
178+-------------------------------------------------------------------------------
179+
113180o_1_space_concat :: Int -> [Benchmark]
114181o_1_space_concat value =
115− [ bgroup "concat"
182+ [ bgroup "concatMapWith"
116183 [ benchIOSrc1
117− "concatMapWithWSerial (2,x/2)"
118− (concatMapWithWSerial 2 (value `div` 2))
184+ "concatMapWithWSerial (n of 1)"
185+ (concatStreamsWith wSerial value 1)
186+ , benchIOSrc1
187+ "concatMapWithWSerial (sqrtVal of sqrtVal)"
188+ (concatStreamsWith wSerial sqrtVal sqrtVal)
189+ -- concatMapWith using StreamD versions of interleave operations are
190+ -- all quadratic, we just measure the sqrtVal benchmark for comparison.
191+ {-
119192 , benchIOSrc1
120− "concatMapWithWSerial (x/2,2)"
121− (concatMapWithWSerial (value `div` 2) 2)
193+ "concatMapWithInterleave (n of 1)"
194+ (concatStreamsWith Internal.interleave value 1)
195+ -}
196+ , benchIOSrc1
197+ "concatMapWithInterleave (sqrtVal of sqrtVal)"
198+ (concatStreamsWith Internal.interleave sqrtVal sqrtVal)
199+ , benchIOSrc1
200+ "concatMapWithRoundrobin (sqrtVal of sqrtVal)"
201+ (concatStreamsWith Internal.roundrobin sqrtVal sqrtVal)
122202 ]
123203 ]
124204
125−{-# INLINE unfoldManyInterleaveRepl4xN #-}
126−unfoldManyInterleaveRepl4xN :: Int -> Int -> IO ()
127−unfoldManyInterleaveRepl4xN value n =
128− S.drain $ Internal.unfoldManyInterleave
129− (UF.lmap return (UF.replicateM 4))
130− (sourceUnfoldrM (value `div` 4) n)
205+ where
131206
132−#ifdef INSPECTION
133−inspect $ hasNoTypeClasses 'unfoldManyInterleaveRepl4xN
134−-- inspect $ 'unfoldManyInterleaveRepl4xN `hasNoType` ''SPEC
135−-- inspect $ 'unfoldManyInterleaveRepl4xN `hasNoType`
136−-- ''D.ConcatUnfoldInterleaveState
137−#endif
207+ sqrtVal = round $ sqrt (fromIntegral value :: Double)
138208
139−{-# INLINE unfoldManyRoundRobinRepl4xN #-}
140−unfoldManyRoundRobinRepl4xN :: Int -> Int -> IO ()
141−unfoldManyRoundRobinRepl4xN value n =
142− S.drain $ Internal.unfoldManyRoundRobin
143− (UF.lmap return (UF.replicateM 4))
144− (sourceUnfoldrM (value `div` 4) n)
209+{-# INLINE concatPairsWithInterleave #-}
210+concatPairsWithInterleave :: Int -> Int -> Int -> IO ()
211+concatPairsWithInterleave = concatPairsWith Internal.interleave
145212
146−#ifdef INSPECTION
147−inspect $ hasNoTypeClasses 'unfoldManyRoundRobinRepl4xN
148−-- inspect $ 'unfoldManyRoundRobinRepl4xN `hasNoType` ''SPEC
149−-- inspect $ 'unfoldManyRoundRobinRepl4xN `hasNoType`
150−-- ''D.ConcatUnfoldInterleaveState
151−#endif
213+{-# INLINE concatPairsWithInterleaveSuffix #-}
214+concatPairsWithInterleaveSuffix :: Int -> Int -> Int -> IO ()
215+concatPairsWithInterleaveSuffix = concatPairsWith Internal.interleaveSuffix
216+
217+{-# INLINE concatPairsWithInterleaveInfix #-}
218+concatPairsWithInterleaveInfix :: Int -> Int -> Int -> IO ()
219+concatPairsWithInterleaveInfix = concatPairsWith Internal.interleaveInfix
220+
221+{-# INLINE concatPairsWithInterleaveMin #-}
222+concatPairsWithInterleaveMin :: Int -> Int -> Int -> IO ()
223+concatPairsWithInterleaveMin = concatPairsWith Internal.interleaveMin
152224
153225o_n_heap_concat :: Int -> [Benchmark]
154226o_n_heap_concat value =
155− [ bgroup "concat"
227+ [ bgroup "concatPairsWith"
156228 [
157− -- interleave x/4 streams of 4 elements each. Needs to buffer
158− -- proportional to x/4. This is different from WSerial because
159− -- WSerial expands slowly because of binary interleave behavior and
160− -- this expands immediately because of Nary interleave behavior.
161229 benchIOSrc1
162− "unfoldManyInterleaveRepl (x/4,4)"
163− (unfoldManyInterleaveRepl4xN value)
230+ "unfoldManyInterleave (n of 1)"
231+ (unfoldManyInterleave value 1)
232+ , benchIOSrc1
233+ "unfoldManyInterleave (sqrtVal of sqrtVal)"
234+ (unfoldManyInterleave sqrtVal sqrtVal)
235+
236+ , benchIOSrc1
237+ "unfoldManyRoundRobin (n of 1)"
238+ (unfoldManyRoundRobin value 1)
239+ , benchIOSrc1
240+ "unfoldManyRoundRobin (sqrtVal of sqrtVal)"
241+ (unfoldManyRoundRobin sqrtVal sqrtVal)
242+
243+ , benchIOSrc1
244+ "concatPairsWithWSerial (n of 1)"
245+ (concatPairsWithWSerial value 1)
164246 , benchIOSrc1
165− "unfoldManyRoundRobinRepl (x/4,4)"
166− (unfoldManyRoundRobinRepl4xN value)
247+ "concatPairsWithWSerial (sqrtVal of sqrtVal)"
248+ (concatPairsWithWSerial sqrtVal sqrtVal)
249+
250+ , benchIOSrc1
251+ "concatPairsWithInterleave (n of 1)"
252+ (concatPairsWithInterleave value 1)
253+ , benchIOSrc1
254+ "concatPairsWithInterleave (sqrtVal of sqrtVal)"
255+ (concatPairsWithInterleave sqrtVal sqrtVal)
256+
257+ , benchIOSrc1
258+ "concatPairsWithInterleaveSuffix (n of 1)"
259+ (concatPairsWithInterleaveSuffix value 1)
260+ , benchIOSrc1
261+ "concatPairsWithInterleaveSuffix (sqrtVal of sqrtVal)"
262+ (concatPairsWithInterleaveSuffix sqrtVal sqrtVal)
263+
264+ , benchIOSrc1
265+ "concatPairsWithInterleaveInfix (n of 1)"
266+ (concatPairsWithInterleaveInfix value 1)
267+ , benchIOSrc1
268+ "concatPairsWithInterleaveInfix (sqrtVal of sqrtVal)"
269+ (concatPairsWithInterleaveInfix sqrtVal sqrtVal)
270+
271+ , benchIOSrc1
272+ "concatPairsWithInterleaveMin (n of 1)"
273+ (concatPairsWithInterleaveMin value 1)
274+ , benchIOSrc1
275+ "concatPairsWithInterleaveMin (sqrtVal of sqrtVal)"
276+ (concatPairsWithInterleaveMin sqrtVal sqrtVal)
277+
278+ , benchIOSrc1
279+ "concatPairsWithRoundrobin (n of 1)"
280+ (concatPairsWithRoundrobin value 1)
281+ , benchIOSrc1
282+ "concatPairsWithRoundrobin (sqrtVal of sqrtVal)"
283+ (concatPairsWithRoundrobin sqrtVal sqrtVal)
167284 ]
168285 ]
169286
287+ where
288+
289+ sqrtVal = round $ sqrt (fromIntegral value :: Double)
290+
170291-------------------------------------------------------------------------------
171292-- Monad
172293-------------------------------------------------------------------------------
173294
174295o_1_space_outerProduct :: Int -> [Benchmark]
175296o_1_space_outerProduct value =
176− [ bgroup "monad-outer-product"
177− [ benchIO "toNullAp" $ toNullAp value fromWSerial
178− , benchIO "toNullM" $ toNullM value fromWSerial
179− , benchIO "toNullM3" $ toNullM3 value fromWSerial
180− , benchIO "filterAllOutM" $ filterAllOutM value fromWSerial
181− , benchIO "filterAllInM" $ filterAllInM value fromWSerial
182− , benchIO "filterSome" $ filterSome value fromWSerial
183− , benchIO "breakAfterSome" $ breakAfterSome value fromWSerial
297+ [ bgroup "outer-product"
298+ [ benchIO
299+ "drain applicative (+) (sqrtVal of sqrtVal)"
300+ (toNullAp value fromWSerial)
301+ , benchIO
302+ "drain monad (+) (sqrtVal of sqrtVal)"
303+ (toNullM value fromWSerial)
304+ , benchIO
305+ "drain monad (+) (cbrtVal of cbrtVal of cbrtVal)"
306+ (toNullM3 value fromWSerial)
307+ , benchIO
308+ "filterAllOut monad (+) (sqrtVal of sqrtVal)"
309+ (filterAllOutM value fromWSerial)
310+ , benchIO
311+ "filterAllIn monad (+) (sqrtVal of sqrtVal)"
312+ (filterAllInM value fromWSerial)
313+ , benchIO
314+ "filterSome monad (+) (sqrtVal of sqrtVal)"
315+ (filterSome value fromWSerial)
316+ , benchIO
317+ "breakAfterSome monad (+) (sqrtVal of sqrtVal)"
318+ (breakAfterSome value fromWSerial)
184319 ]
185320 ]
186321
187322o_n_space_outerProduct :: Int -> [Benchmark]
188323o_n_space_outerProduct value =
189324 [ bgroup
190− "monad-outer-product"
191− [ benchIO "toList" $ toListM value fromWSerial
192− , benchIO "toListSome" $ toListSome value fromWSerial
325+ "outer-product"
326+ [ benchIO
327+ "toList monad (+) (sqrtVal of sqrtVal)"
328+ (toListM value fromWSerial)
329+ , benchIO
330+ "toListSome monad (+) (sqrtVal of sqrtVal)"
331+ (toListSome value fromWSerial)
193332 ]
194333 ]
195334