on a608695 help sign in
619 lines 23 kB history raw
1-- |
2-- Module : Streamly.Benchmark.FileSystem.Handle
3-- Copyright : (c) 2019 Composewell Technologies
4--
5-- License : BSD3
6-- Maintainer : streamly@composewell.com
7-- Stability : experimental
8-- Portability : GHC
10{-# LANGUAGE CPP #-}
11{-# LANGUAGE ScopedTypeVariables #-}
13#ifdef __HADDOCK_VERSION__
14#undef INSPECTION
15#endif
17#ifdef INSPECTION
18{-# LANGUAGE TemplateHaskell #-}
19{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-}
20#endif
22module Handle.ReadWrite
23 (allBenchmarks)
24where
26import Control.Exception (SomeException)
27import System.IO (Handle, hClose, hGetChar)
28import Prelude hiding (last, length)
30import qualified Streamly.Data.Fold as FL
31import qualified Streamly.Unicode.Stream as SS
32import qualified Streamly.FileSystem.Handle as FH
33import qualified Streamly.Internal.Data.Unfold as IUF
34import qualified Streamly.Internal.Unicode.Stream as IUS
35import qualified Streamly.Internal.FileSystem.Handle as IFH
36import qualified Streamly.Internal.Memory.ArrayStream as AS
37import qualified Streamly.Internal.Unicode.Array.Char as IUA
38import qualified Streamly.Internal.Data.Stream.IsStream as IP
39import qualified Streamly.Data.Array.Storable.Foreign as A
40import qualified Streamly.Prelude as S
42import Gauge hiding (env)
43import Handle.Common
45#ifdef INSPECTION
46import Foreign.Storable (Storable)
47import Streamly.Internal.Data.Stream.StreamD.Type (Step(..))
49import qualified Streamly.Internal.Data.Stream.StreamD.Type as D
50import qualified Streamly.Internal.Data.Tuple.Strict as Strict
51import qualified Streamly.Internal.Data.Array.Storable.Foreign as A
52import qualified Streamly.Internal.Data.Array.Storable.Foreign.Types as AT
54import Test.Inspection
55#endif
57-------------------------------------------------------------------------------
58-- copy chunked
59-------------------------------------------------------------------------------
61-- | Copy file
62copyChunks :: Handle -> Handle -> IO ()
63copyChunks inh outh = S.fold (IFH.writeChunks outh) $ IFH.toChunks inh
65#ifdef INSPECTION
66inspect $ hasNoTypeClasses 'copyChunks
67inspect $ 'copyChunks `hasNoType` ''Step
68#endif
70-- | Copy file
71copyCodecUtf8ArraysLenient :: Handle -> Handle -> IO ()
72copyCodecUtf8ArraysLenient inh outh =
73 S.fold (FH.write outh)
74 $ SS.encodeUtf8'
75 $ IUS.decodeUtf8Arrays
76 $ IFH.toChunks inh
78#ifdef INSPECTION
79inspect $ hasNoTypeClasses 'copyCodecUtf8ArraysLenient
80-- inspect $ 'copyCodecUtf8ArraysLenient `hasNoType` ''Step
81#endif
83o_1_space_copy_chunked :: BenchEnv -> [Benchmark]
84o_1_space_copy_chunked env =
85 [ bgroup "copy/toChunks"
86 [ mkBench "toNull" env $ \inH _ ->
87 copyChunks inH (nullH env)
88 , mkBench "raw" env $ \inH outH ->
89 copyChunks inH outH
90 , mkBenchSmall "decodeEncodeUtf8Lenient" env $ \inH outH ->
91 copyCodecUtf8ArraysLenient inH outH
92 ]
93 ]
95-- TBD reading with unfold
97-------------------------------------------------------------------------------
98-- Exceptions readChunks
99-------------------------------------------------------------------------------
101-- | Send the file contents to /dev/null with exception handling
102readChunksOnException :: Handle -> Handle -> IO ()
103readChunksOnException inh devNull =
104 let readEx = IUF.onException (\_ -> hClose inh) FH.readChunks
105 in IUF.fold readEx (IFH.writeChunks devNull) inh
107#ifdef INSPECTION
108inspect $ hasNoTypeClasses 'readChunksOnException
109-- inspect $ 'readChunksOnException `hasNoType` ''Step
110#endif
112-- | Send the file contents to /dev/null with exception handling
113readChunksBracket_ :: Handle -> Handle -> IO ()
114readChunksBracket_ inh devNull =
115 let readEx = IUF.bracket_ return (\_ -> hClose inh) FH.readChunks
116 in IUF.fold readEx (IFH.writeChunks devNull) inh
118#ifdef INSPECTION
119inspect $ hasNoTypeClasses 'readChunksBracket_
120-- inspect $ 'readChunksBracket `hasNoType` ''Step
121#endif
123readChunksBracket :: Handle -> Handle -> IO ()
124readChunksBracket inh devNull =
125 let readEx = IUF.bracket return (\_ -> hClose inh) FH.readChunks
126 in IUF.fold readEx (IFH.writeChunks devNull) inh
128o_1_space_copy_exceptions_readChunks :: BenchEnv -> [Benchmark]
129o_1_space_copy_exceptions_readChunks env =
130 [ bgroup "copy/readChunks/exceptions"
131 [ mkBench "UF.onException" env $ \inH _ ->
132 readChunksOnException inH (nullH env)
133 , mkBench "UF.bracket_" env $ \inH _ ->
134 readChunksBracket_ inH (nullH env)
135 , mkBench "UF.bracket" env $ \inH _ ->
136 readChunksBracket inH (nullH env)
137 ]
138 ]
140-------------------------------------------------------------------------------
141-- Exceptions toChunks
142-------------------------------------------------------------------------------
144-- | Send the file contents to /dev/null with exception handling
145toChunksBracket_ :: Handle -> Handle -> IO ()
146toChunksBracket_ inh devNull =
147 let readEx = IP.bracket_
148 (return ())
149 (\_ -> hClose inh)
150 (\_ -> IFH.toChunks inh)
151 in S.fold (IFH.writeChunks devNull) $ readEx
153#ifdef INSPECTION
154inspect $ hasNoTypeClasses 'toChunksBracket_
155-- inspect $ 'toChunksBracket `hasNoType` ''Step
156#endif
158toChunksBracket :: Handle -> Handle -> IO ()
159toChunksBracket inh devNull =
160 let readEx = S.bracket
161 (return ())
162 (\_ -> hClose inh)
163 (\_ -> IFH.toChunks inh)
164 in S.fold (IFH.writeChunks devNull) $ readEx
166o_1_space_copy_exceptions_toChunks :: BenchEnv -> [Benchmark]
167o_1_space_copy_exceptions_toChunks env =
168 [ bgroup "copy/toChunks/exceptions"
169 [ mkBench "S.bracket_" env $ \inH _ ->
170 toChunksBracket_ inH (nullH env)
171 , mkBench "S.bracket" env $ \inH _ ->
172 toChunksBracket inH (nullH env)
173 ]
174 ]
176-------------------------------------------------------------------------------
177-- copy unfold
178-------------------------------------------------------------------------------
180-- | Copy file
181copyStream :: Handle -> Handle -> IO ()
182copyStream inh outh = S.fold (FH.write outh) (S.unfold FH.read inh)
184#ifdef INSPECTION
185inspect $ hasNoTypeClasses 'copyStream
186inspect $ 'copyStream `hasNoType` ''Step -- S.unfold
187inspect $ 'copyStream `hasNoType` ''IUF.ConcatState -- FH.read/UF.concat
188inspect $ 'copyStream `hasNoType` ''A.ReadUState -- FH.read/A.read
189inspect $ 'copyStream `hasNoType` ''AT.ArrayUnsafe -- FH.write/writeNUnsafe
190inspect $ 'copyStream `hasNoType` ''Strict.Tuple3' -- FH.write/lchunksOf
191#endif
193-- | Copy file
194copyStreamLatin1 :: Handle -> Handle -> IO ()
195copyStreamLatin1 inh outh =
196 S.fold (FH.write outh)
197 $ SS.encodeLatin1'
198 $ SS.decodeLatin1
199 $ S.unfold FH.read inh
201#ifdef INSPECTION
202inspect $ hasNoTypeClasses 'copyStreamLatin1
203inspect $ 'copyStreamLatin1 `hasNoType` ''Step
204inspect $ 'copyStreamLatin1 `hasNoType` ''IUF.ConcatState -- FH.read/UF.concat
205inspect $ 'copyStreamLatin1 `hasNoType` ''A.ReadUState -- FH.read/A.read
206inspect $ 'copyStreamLatin1 `hasNoType` ''AT.ArrayUnsafe -- FH.write/writeNUnsafe
207inspect $ 'copyStreamLatin1 `hasNoType` ''Strict.Tuple3' -- FH.write/lchunksOf
208#endif
210-- | Copy file
211_copyStreamUtf8' :: Handle -> Handle -> IO ()
212_copyStreamUtf8' inh outh =
213 S.fold (FH.write outh)
214 $ SS.encodeUtf8'
215 $ SS.decodeUtf8'
216 $ S.unfold FH.read inh
218#ifdef INSPECTION
219inspect $ hasNoTypeClasses '_copyStreamUtf8'
220-- inspect $ '_copyStreamUtf8 `hasNoType` ''Step
221-- inspect $ '_copyStreamUtf8 `hasNoType` ''AT.FlattenState
222-- inspect $ '_copyStreamUtf8 `hasNoType` ''D.ConcatMapUState
223#endif
225-- | Copy file
226copyStreamUtf8 :: Handle -> Handle -> IO ()
227copyStreamUtf8 inh outh =
228 S.fold (FH.write outh)
229 $ SS.encodeUtf8
230 $ SS.decodeUtf8
231 $ S.unfold FH.read inh
233#ifdef INSPECTION
234inspect $ hasNoTypeClasses 'copyStreamUtf8
235-- inspect $ 'copyStreamUtf8Lax `hasNoType` ''Step
236-- inspect $ 'copyStreamUtf8Lax `hasNoType` ''AT.FlattenState
237-- inspect $ 'copyStreamUtf8Lax `hasNoType` ''D.ConcatMapUState
238#endif
240o_1_space_copy_read :: BenchEnv -> [Benchmark]
241o_1_space_copy_read env =
242 [ bgroup "copy/read"
243 [ mkBench "rawToNull" env $ \inh _ ->
244 copyStream inh (nullH env)
245 , mkBench "rawToFile" env $ \inh outh ->
246 copyStream inh outh
247 -- This needs an ascii file, as decode just errors out.
248 , mkBench "SS.encodeLatin1' . SS.decodeLatin1" env $ \inh outh ->
249 copyStreamLatin1 inh outh
250#ifdef DEVBUILD
251 , mkBench "copyUtf8" env $ \inh outh ->
252 _copyStreamUtf8' inh outh
253#endif
254 , mkBenchSmall "SS.encodeUtf8 . SS.decodeUtf8Lax" env $ \inh outh ->
255 copyStreamUtf8 inh outh
256 ]
257 ]
259-------------------------------------------------------------------------------
260-- copy stream
261-------------------------------------------------------------------------------
263-- | Send the file contents to /dev/null
264readFromBytesNull :: Handle -> Handle -> IO ()
265readFromBytesNull inh devNull = IFH.fromBytes devNull $ S.unfold FH.read inh
267#ifdef INSPECTION
268inspect $ hasNoTypeClasses 'readFromBytesNull
269inspect $ 'readFromBytesNull `hasNoType` ''Step
270inspect $ 'readFromBytesNull `hasNoType` ''AT.SpliceState
271inspect $ 'readFromBytesNull `hasNoType` ''AT.ArrayUnsafe -- FH.fromBytes/S.arraysOf
272inspect $ 'readFromBytesNull `hasNoType` ''D.GroupState
273#endif
275o_1_space_copy_fromBytes :: BenchEnv -> [Benchmark]
276o_1_space_copy_fromBytes env =
277 [ bgroup "copy/fromBytes"
278 [ mkBench "rawToNull" env $ \inh _ ->
279 readFromBytesNull inh (nullH env)
280 ]
281 ]
283-------------------------------------------------------------------------------
284-- unfold exceptions
285-------------------------------------------------------------------------------
287-- | Send the file contents to /dev/null with exception handling
288readWriteOnExceptionUnfold :: Handle -> Handle -> IO ()
289readWriteOnExceptionUnfold inh devNull =
290 let readEx = IUF.onException (\_ -> hClose inh) FH.read
291 in S.fold (FH.write devNull) $ S.unfold readEx inh
293#ifdef INSPECTION
294inspect $ hasNoTypeClasses 'readWriteOnExceptionUnfold
295-- inspect $ 'readWriteOnExceptionUnfold `hasNoType` ''Step
296#endif
298-- | Send the file contents to /dev/null with exception handling
299readWriteHandleExceptionUnfold :: Handle -> Handle -> IO ()
300readWriteHandleExceptionUnfold inh devNull =
301 let handler (_e :: SomeException) = hClose inh >> return 10
302 readEx = IUF.handle (IUF.singletonM handler) FH.read
303 in S.fold (FH.write devNull) $ S.unfold readEx inh
305#ifdef INSPECTION
306inspect $ hasNoTypeClasses 'readWriteHandleExceptionUnfold
307-- inspect $ 'readWriteHandleExceptionUnfold `hasNoType` ''Step
308#endif
310-- | Send the file contents to /dev/null with exception handling
311readWriteFinally_Unfold :: Handle -> Handle -> IO ()
312readWriteFinally_Unfold inh devNull =
313 let readEx = IUF.finally_ (\_ -> hClose inh) FH.read
314 in S.fold (FH.write devNull) $ S.unfold readEx inh
316#ifdef INSPECTION
317inspect $ hasNoTypeClasses 'readWriteFinally_Unfold
318-- inspect $ 'readWriteFinallyUnfold `hasNoType` ''Step
319#endif
321readWriteFinallyUnfold :: Handle -> Handle -> IO ()
322readWriteFinallyUnfold inh devNull =
323 let readEx = IUF.finally (\_ -> hClose inh) FH.read
324 in S.fold (FH.write devNull) $ S.unfold readEx inh
326-- | Send the file contents to /dev/null with exception handling
327readWriteBracket_Unfold :: Handle -> Handle -> IO ()
328readWriteBracket_Unfold inh devNull =
329 let readEx = IUF.bracket_ return (\_ -> hClose inh) FH.read
330 in S.fold (FH.write devNull) $ S.unfold readEx inh
332#ifdef INSPECTION
333inspect $ hasNoTypeClasses 'readWriteBracket_Unfold
334-- inspect $ 'readWriteBracketUnfold `hasNoType` ''Step
335#endif
337readWriteBracketUnfold :: Handle -> Handle -> IO ()
338readWriteBracketUnfold inh devNull =
339 let readEx = IUF.bracket return (\_ -> hClose inh) FH.read
340 in S.fold (FH.write devNull) $ S.unfold readEx inh
342o_1_space_copy_read_exceptions :: BenchEnv -> [Benchmark]
343o_1_space_copy_read_exceptions env =
344 [ bgroup "copy/read/exceptions"
345 [ mkBenchSmall "UF.onException" env $ \inh _ ->
346 readWriteOnExceptionUnfold inh (nullH env)
347 , mkBenchSmall "UF.handle" env $ \inh _ ->
348 readWriteHandleExceptionUnfold inh (nullH env)
349 , mkBenchSmall "UF.finally_" env $ \inh _ ->
350 readWriteFinally_Unfold inh (nullH env)
351 , mkBenchSmall "UF.finally" env $ \inh _ ->
352 readWriteFinallyUnfold inh (nullH env)
353 , mkBenchSmall "UF.bracket_" env $ \inh _ ->
354 readWriteBracket_Unfold inh (nullH env)
355 , mkBenchSmall "UF.bracket" env $ \inh _ ->
356 readWriteBracketUnfold inh (nullH env)
357 ]
358 ]
360-------------------------------------------------------------------------------
361-- stream exceptions
362-------------------------------------------------------------------------------
364-- | Send the file contents to /dev/null with exception handling
365readWriteOnExceptionStream :: Handle -> Handle -> IO ()
366readWriteOnExceptionStream inh devNull =
367 let readEx = S.onException (hClose inh) (S.unfold FH.read inh)
368 in S.fold (FH.write devNull) $ readEx
370-- | Send the file contents to /dev/null with exception handling
371readWriteHandleExceptionStream :: Handle -> Handle -> IO ()
372readWriteHandleExceptionStream inh devNull =
373 let handler (_e :: SomeException) = S.yieldM (hClose inh >> return 10)
374 readEx = S.handle handler (S.unfold FH.read inh)
375 in S.fold (FH.write devNull) $ readEx
377-- | Send the file contents to /dev/null with exception handling
378readWriteFinally_Stream :: Handle -> Handle -> IO ()
379readWriteFinally_Stream inh devNull =
380 let readEx = IP.finally_ (hClose inh) (S.unfold FH.read inh)
381 in S.fold (FH.write devNull) readEx
383readWriteFinallyStream :: Handle -> Handle -> IO ()
384readWriteFinallyStream inh devNull =
385 let readEx = S.finally (hClose inh) (S.unfold FH.read inh)
386 in S.fold (FH.write devNull) readEx
388-- | Send the file contents to /dev/null with exception handling
389fromToBytesBracket_Stream :: Handle -> Handle -> IO ()
390fromToBytesBracket_Stream inh devNull =
391 let readEx = IP.bracket_ (return ()) (\_ -> hClose inh)
392 (\_ -> IFH.toBytes inh)
393 in IFH.fromBytes devNull $ readEx
395#ifdef INSPECTION
396inspect $ hasNoTypeClasses 'fromToBytesBracket_Stream
397-- inspect $ 'fromToBytesBracketStream `hasNoType` ''Step
398#endif
400fromToBytesBracketStream :: Handle -> Handle -> IO ()
401fromToBytesBracketStream inh devNull =
402 let readEx = S.bracket (return ()) (\_ -> hClose inh)
403 (\_ -> IFH.toBytes inh)
404 in IFH.fromBytes devNull $ readEx
406readWriteBeforeAfterStream :: Handle -> Handle -> IO ()
407readWriteBeforeAfterStream inh devNull =
408 let readEx =
409 IP.after (hClose inh)
410 $ IP.before (hGetChar inh) (S.unfold FH.read inh)
411 in S.fold (FH.write devNull) readEx
413readWriteAfterStream :: Handle -> Handle -> IO ()
414readWriteAfterStream inh devNull =
415 let readEx = IP.after (hClose inh) (S.unfold FH.read inh)
416 in S.fold (FH.write devNull) readEx
418readWriteAfter_Stream :: Handle -> Handle -> IO ()
419readWriteAfter_Stream inh devNull =
420 let readEx = IP.after_ (hClose inh) (S.unfold FH.read inh)
421 in S.fold (FH.write devNull) readEx
423o_1_space_copy_stream_exceptions :: BenchEnv -> [Benchmark]
424o_1_space_copy_stream_exceptions env =
425 [ bgroup "copy/read/exceptions"
426 [ mkBenchSmall "S.onException" env $ \inh _ ->
427 readWriteOnExceptionStream inh (nullH env)
428 , mkBenchSmall "S.handle" env $ \inh _ ->
429 readWriteHandleExceptionStream inh (nullH env)
430 , mkBenchSmall "S.finally_" env $ \inh _ ->
431 readWriteFinally_Stream inh (nullH env)
432 , mkBenchSmall "S.finally" env $ \inh _ ->
433 readWriteFinallyStream inh (nullH env)
434 , mkBenchSmall "S.after . S.before" env $ \inh _ ->
435 readWriteBeforeAfterStream inh (nullH env)
436 , mkBenchSmall "S.after" env $ \inh _ ->
437 readWriteAfterStream inh (nullH env)
438 , mkBenchSmall "S.after_" env $ \inh _ ->
439 readWriteAfter_Stream inh (nullH env)
440 ]
441 , bgroup "copy/fromToBytes/exceptions"
442 [ mkBenchSmall "S.bracket_" env $ \inh _ ->
443 fromToBytesBracket_Stream inh (nullH env)
444 , mkBenchSmall "S.bracket" env $ \inh _ ->
445 fromToBytesBracketStream inh (nullH env)
446 ]
447 ]
449-------------------------------------------------------------------------------
450-- copy with group/ungroup transformations
451-------------------------------------------------------------------------------
453-- | Lines and unlines
454copyChunksSplitInterposeSuffix :: Handle -> Handle -> IO ()
455copyChunksSplitInterposeSuffix inh outh =
456 S.fold (IFH.write outh)
457 $ AS.interposeSuffix 10
458 $ AS.splitOnSuffix 10
459 $ IFH.toChunks inh
461#ifdef INSPECTION
462inspect $ hasNoTypeClassesExcept 'copyChunksSplitInterposeSuffix [''Storable]
463-- inspect $ 'copyChunksSplitInterposeSuffix `hasNoType` ''Step
464#endif
466-- | Words and unwords
467copyChunksSplitInterpose :: Handle -> Handle -> IO ()
468copyChunksSplitInterpose inh outh =
469 S.fold (IFH.write outh)
470 $ AS.interpose 32
471 -- XXX this is not correct word splitting combinator
472 $ AS.splitOn 32
473 $ IFH.toChunks inh
475#ifdef INSPECTION
476inspect $ hasNoTypeClassesExcept 'copyChunksSplitInterpose [''Storable]
477-- inspect $ 'copyChunksSplitInterpose `hasNoType` ''Step
478#endif
480o_1_space_copy_toChunks_group_ungroup :: BenchEnv -> [Benchmark]
481o_1_space_copy_toChunks_group_ungroup env =
482 [ bgroup "copy/toChunks/group-ungroup"
483 [ mkBench "AS.interposeSuffix . AS.splitOnSuffix" env $ \inh outh ->
484 copyChunksSplitInterposeSuffix inh outh
485 , mkBenchSmall "AS.interpose . AS.splitOn" env $ \inh outh ->
486 copyChunksSplitInterpose inh outh
487 ]
488 ]
490-------------------------------------------------------------------------------
491-- copy with group/ungroup transformations
492-------------------------------------------------------------------------------
494linesUnlinesCopy :: Handle -> Handle -> IO ()
495linesUnlinesCopy inh outh =
496 S.fold (FH.write outh)
497 $ SS.encodeLatin1'
498 $ IUS.unlines IUF.fromList
499 $ S.splitOnSuffix (== '\n') FL.toList
500 $ SS.decodeLatin1
501 $ S.unfold FH.read inh
503linesUnlinesArrayWord8Copy :: Handle -> Handle -> IO ()
504linesUnlinesArrayWord8Copy inh outh =
505 S.fold (FH.write outh)
506 $ IP.interposeSuffix 10 A.read
507 $ S.splitOnSuffix (== 10) A.write
508 $ S.unfold FH.read inh
510-- XXX splitSuffixOn requires -funfolding-use-threshold=150 for better fusion
511-- | Lines and unlines
512linesUnlinesArrayCharCopy :: Handle -> Handle -> IO ()
513linesUnlinesArrayCharCopy inh outh =
514 S.fold (FH.write outh)
515 $ SS.encodeLatin1'
516 $ IUA.unlines
517 $ IUA.lines
518 $ SS.decodeLatin1
519 $ S.unfold FH.read inh
521#ifdef INSPECTION
522inspect $ hasNoTypeClassesExcept 'linesUnlinesArrayCharCopy [''Storable]
523-- inspect $ 'linesUnlinesArrayCharCopy `hasNoType` ''Step
524#endif
526-- XXX to write this we need to be able to map decodeUtf8 on the A.read fold.
527-- For that we have to write decodeUtf8 as a Pipe.
528{-
529{-# INLINE linesUnlinesArrayUtf8Copy #-}
530linesUnlinesArrayUtf8Copy :: Handle -> Handle -> IO ()
531linesUnlinesArrayUtf8Copy inh outh =
532 S.fold (FH.write outh)
533 $ SS.encodeLatin1'
534 $ IP.intercalate (A.fromList [10]) (pipe SS.decodeUtf8P A.read)
535 $ S.splitOnSuffix (== '\n') (IFL.lmap SS.encodeUtf8' A.write)
536 $ SS.decodeLatin1
537 $ S.unfold FH.read inh
538-}
540-- | Word, unwords and copy
541wordsUnwordsCopyWord8 :: Handle -> Handle -> IO ()
542wordsUnwordsCopyWord8 inh outh =
543 S.fold (FH.write outh)
544 $ IP.interposeSuffix 32 IUF.fromList
545 $ S.wordsBy isSp FL.toList
546 $ S.unfold FH.read inh
548#ifdef INSPECTION
549inspect $ hasNoTypeClasses 'wordsUnwordsCopyWord8
550-- inspect $ 'wordsUnwordsCopyWord8 `hasNoType` ''Step
551#endif
553-- | Word, unwords and copy
554wordsUnwordsCopy :: Handle -> Handle -> IO ()
555wordsUnwordsCopy inh outh =
556 S.fold (FH.write outh)
557 $ SS.encodeLatin1'
558 $ IUS.unwords IUF.fromList
559 -- XXX This pipeline does not fuse with wordsBy but fuses with splitOn
560 -- with -funfolding-use-threshold=300. With wordsBy it does not fuse
561 -- even with high limits for inlining and spec-constr ghc options. With
562 -- -funfolding-use-threshold=400 it performs pretty well and there
563 -- is no evidence in the core that a join point involving Step
564 -- constructors is not getting inlined. Not being able to fuse at all in
565 -- this case could be an unknown issue, need more investigation.
566 $ S.wordsBy isSpace FL.toList
567 -- -- $ S.splitOn isSpace FL.toList
568 $ SS.decodeLatin1
569 $ S.unfold FH.read inh
571#ifdef INSPECTION
572-- inspect $ hasNoTypeClasses 'wordsUnwordsCopy
573-- inspect $ 'wordsUnwordsCopy `hasNoType` ''Step
574#endif
576wordsUnwordsCharArrayCopy :: Handle -> Handle -> IO ()
577wordsUnwordsCharArrayCopy inh outh =
578 S.fold (FH.write outh)
579 $ SS.encodeLatin1'
580 $ IUA.unwords
581 $ IUA.words
582 $ SS.decodeLatin1
583 $ S.unfold FH.read inh
585o_1_space_copy_read_group_ungroup :: BenchEnv -> [Benchmark]
586o_1_space_copy_read_group_ungroup env =
587 [ bgroup "copy/read/group-ungroup"
588 [ mkBenchSmall "US.unlines . S.splitOnSuffix ([Word8])" env
589 $ \inh outh -> linesUnlinesCopy inh outh
590 , mkBenchSmall "S.interposeSuffix . S.splitOnSuffix(Array Word8)" env
591 $ \inh outh -> linesUnlinesArrayWord8Copy inh outh
592 , mkBenchSmall "UA.unlines . UA.lines (Array Char)" env
593 $ \inh outh -> linesUnlinesArrayCharCopy inh outh
595 , mkBenchSmall "S.interposeSuffix . S.wordsBy ([Word8])" env
596 $ \inh outh -> wordsUnwordsCopyWord8 inh outh
597 , mkBenchSmall "US.unwords . S.wordsBy ([Char])" env
598 $ \inh outh -> wordsUnwordsCopy inh outh
599 , mkBenchSmall "UA.unwords . UA.words (Array Char)" env
600 $ \inh outh -> wordsUnwordsCharArrayCopy inh outh
601 ]
602 ]
604-------------------------------------------------------------------------------
605--
606-------------------------------------------------------------------------------
608allBenchmarks :: BenchEnv -> [Benchmark]
609allBenchmarks env = Prelude.concat
610 [ o_1_space_copy_chunked env
611 , o_1_space_copy_exceptions_readChunks env
612 , o_1_space_copy_exceptions_toChunks env
613 , o_1_space_copy_read env
614 , o_1_space_copy_fromBytes env
615 , o_1_space_copy_read_exceptions env
616 , o_1_space_copy_stream_exceptions env
617 , o_1_space_copy_toChunks_group_ungroup env
618 , o_1_space_copy_read_group_ungroup env
619 ]