Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
2fca5c8
Use fusion-plugin werror only in inspection build
harendra-kumar Jul 12, 2026
20034ee
Update bench-runner cabal.project config
harendra-kumar Jul 14, 2026
a18f683
Use latest fusion-plugin for core-size reporting
harendra-kumar Jul 14, 2026
c2fd369
Add core-sizes comparison in the perf regression CI
harendra-kumar Jul 17, 2026
6397c5e
Add fusion anns in Stream/Unfold/Scanl benchmarks
harendra-kumar Jul 12, 2026
54eade9
Rename benchmarks after the functions they benchmark
harendra-kumar Jul 20, 2026
5c2f01a
Sync Data.Fold bench names with benchmarked functions
harendra-kumar Jul 20, 2026
4a2c5d3
Move randomRIO out of benchmarked actions in Fold bench
harendra-kumar Jul 20, 2026
6ebf409
Move randomRIO call out of benchmarked actions
harendra-kumar Jul 20, 2026
dfed390
Fix fusion-plugin violations in the Data.Fold benchmark
harendra-kumar Jul 20, 2026
ad268c3
Update fusion-plugin commit tag
harendra-kumar Jul 20, 2026
4b4fbc2
fixup: Data.Fold add a not fusing comment
harendra-kumar Jul 20, 2026
48893c6
Fixup: Data.Fold increase build memory
harendra-kumar Jul 20, 2026
a6e8001
Add benchmark naming guidelines to Stream benchmarks
harendra-kumar Jul 21, 2026
76db02d
Add benchmark naming guidelines to Scanl benchmarks
harendra-kumar Jul 21, 2026
eb50f7d
Add benchmark naming guidelines to Unfold benchmarks
harendra-kumar Jul 21, 2026
ca356c9
Add fusion anns in CrossModule benchmark
harendra-kumar Jul 21, 2026
d872ae9
Update fusion-plugin commit tag
harendra-kumar Jul 21, 2026
4d14290
Rename benchmarks and add fusion anns to Array benchmarks
harendra-kumar Jul 21, 2026
94edd38
Update bench-report commit tag, for --keep-going option
harendra-kumar Jul 22, 2026
89f7119
Export some state types for fusion inspection
harendra-kumar Jul 22, 2026
08b2ff8
fixup: bench-report commit tag
harendra-kumar Jul 22, 2026
6a26453
Rename benchmarks and add fusion plugin annotations
harendra-kumar Jul 22, 2026
aae7ca8
Update fusion-plugin commit tag
harendra-kumar Jul 24, 2026
f5140dc
Update annotations, unqualified types, remove boundary types
harendra-kumar Jul 24, 2026
0067aeb
Add --keep-going for master branch bench-runner
harendra-kumar Jul 25, 2026
de508eb
Export state types for inspection annotations
harendra-kumar Jul 25, 2026
1e68381
fixup: non-inspeciton build, ParserK annotations
harendra-kumar Jul 25, 2026
e61cfbb
Fixup: continue on error on master branch bench-runner
harendra-kumar Jul 25, 2026
ee318b4
Fix bench renaming in bench-runner
harendra-kumar Jul 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/regression-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ jobs:
- name: Run benchmarks for "master" branch
run: |
# --cabal-build-options "-j1"
./bench-runner --package-name streamly-benchmarks --package-version 0.0.0 --targets "$CI_BENCHMARKS" --raw
./bench-runner --package-name streamly-benchmarks --package-version 0.0.0 --targets "$CI_BENCHMARKS" --core-sizes
./bench-runner --package-name streamly-benchmarks --package-version 0.0.0 --targets "$CI_BENCHMARKS" --raw --keep-going || true
# XXX Print dependencies of streamly-core and streamly for comparison
# in case there is a regression due to version changes.
# ghc-pkg --package-db=./dist-newstyle/packagedb/ghc-9.10.3/ field streamly depends
Expand All @@ -159,6 +160,7 @@ jobs:
- name: Run benchmarks and append
run: |
# --cabal-build-options "-j1"
./bench-runner --package-name streamly-benchmarks --package-version 0.0.0 --targets "$CI_BENCHMARKS" --core-sizes --append
./bench-runner --package-name streamly-benchmarks --package-version 0.0.0 --targets "$CI_BENCHMARKS" --raw --append

# -----------------------------------------------------------------
Expand All @@ -167,6 +169,7 @@ jobs:

- name: List all benchmarks
run: |
./bench-runner --package-name streamly-benchmarks --package-version 0.0.0 --targets "$CI_BENCHMARKS" --core-sizes --no-measure
./bench-runner --package-name streamly-benchmarks --package-version 0.0.0 --targets "$CI_BENCHMARKS" --no-measure

- name: Compare benchmarks
Expand Down
83 changes: 83 additions & 0 deletions benchmark/Streamly/Benchmark/CrossModule/FileSystem.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,16 @@ module CrossModule.FileSystem (benchmarks) where

import Data.Functor.Identity (runIdentity)
import Data.Word (Word8)
import Foreign.Ptr (Ptr)
import GHC.Classes (IP)
import GHC.Magic (inline)
import GHC.Magic (noinline)
import GHC.Stack (CallStack, SrcLoc)
import Streamly.Internal.Data.Array (Array)
import Streamly.Internal.Data.MutArray (MutArray)
import Streamly.Internal.Data.MutByteArray (PinnedState)
import System.IO (Handle)
import Unsafe.Coerce (UnsafeEquality)

import qualified Streamly.Data.Fold as Fold
import qualified Streamly.FileSystem.Handle as FH
Expand All @@ -38,6 +45,7 @@ import qualified Streamly.Internal.Data.Parser as PR
import qualified Streamly.Internal.Data.Stream as IP
import qualified Streamly.Data.Stream as S

import Fusion.Plugin.Types
import Test.Tasty.Bench hiding (env)
import Prelude hiding (last, length)
import Streamly.Benchmark.Common
Expand All @@ -58,6 +66,13 @@ import Test.Inspection
-------------------------------------------------------------------------------

-- | Get the last byte from a file bytestream.
{-# ANN readLast (PermitPatternMatches
[''[],''Int,''UnsafeEquality,''IO,''Array]) #-}
{-# ANN readLast (PermitConstructions
[''Int,''SrcLoc,''CallStack,''[],''Array,''Maybe,''Word8,''Ptr
,''PinnedState]) #-}
{-# ANN readLast (PermitTypeClasses [''IP]) #-}
{-# NOINLINE readLast #-}
readLast :: Handle -> IO (Maybe Word8)
readLast = S.fold Fold.latest . S.unfold FH.reader

Expand All @@ -69,6 +84,12 @@ inspect $ 'readLast `hasNoType` ''MutArray.ArrayUnsafe -- FH.read/A.read
#endif

-- | Count the number of bytes in a file.
{-# ANN readCountBytes (PermitPatternMatches
[''[],''Int,''UnsafeEquality,''IO,''Array]) #-}
{-# ANN readCountBytes (PermitConstructions
[''Int,''SrcLoc,''CallStack,''[],''Array,''Ptr,''PinnedState]) #-}
{-# ANN readCountBytes (PermitTypeClasses [''IP]) #-}
{-# NOINLINE readCountBytes #-}
readCountBytes :: Handle -> IO Int
readCountBytes = S.fold Fold.length . S.unfold FH.reader

Expand All @@ -80,6 +101,12 @@ inspect $ 'readCountBytes `hasNoType` ''MutArray.ArrayUnsafe -- FH.read/A.read
#endif

-- | Sum the bytes in a file.
{-# ANN readSumBytes (PermitPatternMatches
[''[],''Int,''UnsafeEquality,''IO,''Array]) #-}
{-# ANN readSumBytes (PermitConstructions
[''Int,''SrcLoc,''CallStack,''[],''Array,''Word8,''Ptr,''PinnedState]) #-}
{-# ANN readSumBytes (PermitTypeClasses [''IP]) #-}
{-# NOINLINE readSumBytes #-}
readSumBytes :: Handle -> IO Word8
readSumBytes = S.fold Fold.sum . S.unfold FH.reader

Expand All @@ -94,10 +121,21 @@ inspect $ 'readSumBytes `hasNoType` ''MutArray.ArrayUnsafe -- FH.read/A.read
-- reduce after grouping in chunks
-------------------------------------------------------------------------------

{-# ANN chunksOfSum (PermitPatternMatches
[''[],''Int,''UnsafeEquality,''IO,''Array]) #-}
{-# ANN chunksOfSum (PermitConstructions
[''Int,''SrcLoc,''CallStack,''[],''Array,''Ptr,''PinnedState]) #-}
{-# ANN chunksOfSum (PermitTypeClasses [''IP]) #-}
{-# NOINLINE chunksOfSum #-}
chunksOfSum :: Int -> Handle -> IO Int
chunksOfSum n inh =
S.fold Fold.length $ IP.groupsOf n FL.sum (S.unfold FH.reader inh)

-- NOTE: these three rely on the caller applying 'inline'/'noinline' (GHC.Magic)
-- at each call site to get either a fully inlined or a real out-of-line call
-- from the same definition, so they are intentionally left without a NOINLINE
-- pragma/ANN -- adding NOINLINE here would remove the unfolding that 'inline'
-- needs and defeat the small-n variant.
foldMany1ChunksOfSum :: Int -> Handle -> IO Int
foldMany1ChunksOfSum n inh =
S.fold Fold.length
Expand Down Expand Up @@ -143,6 +181,13 @@ chunksOf n inh =
-------------------------------------------------------------------------------

-- | Get the last byte from a file bytestream.
{-# ANN toChunksLast (PermitPatternMatches
[''[],''Int,''UnsafeEquality,''IO,''Array]) #-}
{-# ANN toChunksLast (PermitConstructions
[''Int,''SrcLoc,''CallStack,''[],''Array,''Maybe,''Word8,''Ptr
,''PinnedState]) #-}
{-# ANN toChunksLast (PermitTypeClasses [''IP]) #-}
{-# NOINLINE toChunksLast #-}
toChunksLast :: Handle -> IO (Maybe Word8)
toChunksLast inh = do
let s = FH.readChunks inh
Expand All @@ -157,6 +202,12 @@ inspect $ 'toChunksLast `hasNoType` ''Step
#endif

-- | Count the number of bytes in a file.
{-# ANN toChunksSumLengths (PermitPatternMatches
[''[],''Int,''UnsafeEquality,''IO,''Array]) #-}
{-# ANN toChunksSumLengths (PermitConstructions
[''Int,''SrcLoc,''CallStack,''[],''Array,''Ptr,''PinnedState]) #-}
{-# ANN toChunksSumLengths (PermitTypeClasses [''IP]) #-}
{-# NOINLINE toChunksSumLengths #-}
toChunksSumLengths :: Handle -> IO Int
toChunksSumLengths inh =
let s = FH.readChunks inh
Expand All @@ -168,6 +219,12 @@ inspect $ 'toChunksSumLengths `hasNoType` ''Step
#endif

-- | Sum the bytes in a file.
{-# ANN toChunksCountBytes (PermitPatternMatches
[''[],''Int,''UnsafeEquality,''IO,''Array]) #-}
{-# ANN toChunksCountBytes (PermitConstructions
[''Int,''SrcLoc,''CallStack,''[],''Array,''Ptr,''PinnedState]) #-}
{-# ANN toChunksCountBytes (PermitTypeClasses [''IP]) #-}
{-# NOINLINE toChunksCountBytes #-}
toChunksCountBytes :: Handle -> IO Word8
toChunksCountBytes inh = do
let foldlArr' f z = runIdentity . IP.foldl' f z . A.read
Expand All @@ -184,6 +241,13 @@ inspect $ 'toChunksCountBytes `hasNoType` ''Step
-------------------------------------------------------------------------------

-- | Count the number of lines in a file.
{-# ANN toChunksSplitOnSuffix (PermitPatternMatches
[''[],''Int,''UnsafeEquality,''IO,''MutArray,''Array]) #-}
{-# ANN toChunksSplitOnSuffix (PermitConstructions
[''Int,''SrcLoc,''CallStack,''[],''Array,''MutArray,''Ptr
,''PinnedState]) #-}
{-# ANN toChunksSplitOnSuffix (PermitTypeClasses [''IP]) #-}
{-# NOINLINE toChunksSplitOnSuffix #-}
toChunksSplitOnSuffix :: Handle -> IO Int
toChunksSplitOnSuffix =
IP.fold Fold.length
Expand All @@ -196,6 +260,13 @@ inspect $ 'toChunksSplitOnSuffix `hasNoType` ''Step
#endif

-- | Count the number of words in a file.
{-# ANN toChunksSplitOn (PermitPatternMatches
[''[],''Int,''UnsafeEquality,''IO,''MutArray,''Array]) #-}
{-# ANN toChunksSplitOn (PermitConstructions
[''Int,''SrcLoc,''CallStack,''[],''Array,''MutArray,''Ptr
,''PinnedState]) #-}
{-# ANN toChunksSplitOn (PermitTypeClasses [''IP]) #-}
{-# NOINLINE toChunksSplitOn #-}
toChunksSplitOn :: Handle -> IO Int
toChunksSplitOn =
IP.fold Fold.length
Expand All @@ -212,6 +283,12 @@ inspect $ 'toChunksSplitOn `hasNoType` ''Step
-------------------------------------------------------------------------------

-- | Lines and unlines
{-# ANN copyChunksSplitInterposeSuffix (PermitPatternMatches
[''IO,''[],''Int,''UnsafeEquality,''Array,''MutArray]) #-}
{-# ANN copyChunksSplitInterposeSuffix (PermitConstructions
[''Int,''SrcLoc,''CallStack,''[],''Array,''(),''MutArray,''Ptr,''Bool
,''PinnedState]) #-}
{-# ANN copyChunksSplitInterposeSuffix (PermitTypeClasses [''IP]) #-}
{-# NOINLINE copyChunksSplitInterposeSuffix #-}
copyChunksSplitInterposeSuffix :: Handle -> Handle -> IO ()
copyChunksSplitInterposeSuffix inh outh =
Expand All @@ -225,6 +302,12 @@ inspect $ 'copyChunksSplitInterposeSuffix `hasNoType` ''Step
#endif

-- | Words and unwords
{-# ANN copyChunksSplitInterpose (PermitPatternMatches
[''IO,''[],''Int,''UnsafeEquality,''MutArray,''Array,''(,),''Maybe]) #-}
{-# ANN copyChunksSplitInterpose (PermitConstructions
[''Int,''SrcLoc,''CallStack,''[],''Array,''(,),''MutArray,''Maybe,''()
,''Ptr,''Bool,''PinnedState]) #-}
{-# ANN copyChunksSplitInterpose (PermitTypeClasses [''IP]) #-}
{-# NOINLINE copyChunksSplitInterpose #-}
copyChunksSplitInterpose :: Handle -> Handle -> IO ()
copyChunksSplitInterpose inh outh =
Expand Down
Loading
Loading