streamly/benchmark/streamly-benchmarks.cabal
Harendra Kumar 55d49bd50c Optimize Functor/Applicative/Monad etc for serial
Some of the benchmarks were order of magnitude off due to missing INLINE for
type class operations. Now, all of them are in reasonable limits. Benchmarks
affected for serial streams:

* Functor, Applicative, Monad, transformers

We need to do a similar exercise for other types of streams and for
folds/parsers as well.
2020-06-23 13:41:41 +05:30

429 lines
12 KiB
Plaintext

cabal-version: 2.2
name: streamly-benchmarks
version: 0.0.0
synopsis: Benchmarks for streamly
description: Benchmarks are separated from the main package because we
want to have a library for benchmarks to reuse the code across different
benchmark executables. For example, we have common benchmarking code for
different types of streams. We need different benchmarking executables
for serial, async, ahead style streams, therefore, we need to use
the common code in several benchmarks, just changing the type of
the stream. It takes a long time to compile this file and it gets
compiled for each benchmarks once if we do not have a library. Cabal
does no support internal libraries without per-component builds and
per-component builds are not supported with Configure, so we are not
left with any other choice.
flag fusion-plugin
description: Use fusion plugin for benchmarks and executables
manual: True
default: False
flag inspection
description: Enable inspection testing
manual: True
default: False
flag debug
description: Debug build with asserts enabled
manual: True
default: False
flag dev
description: Development build
manual: True
default: False
flag has-llvm
description: Use llvm backend for better performance
manual: True
default: False
flag no-charts
description: Disable benchmark charts in development build
manual: True
default: False
-------------------------------------------------------------------------------
-- Common stanzas
-------------------------------------------------------------------------------
common compile-options
default-language: Haskell2010
if flag(dev)
cpp-options: -DDEVBUILD
if flag(inspection)
cpp-options: -DINSPECTION
ghc-options: -Wall
if flag(has-llvm)
ghc-options: -fllvm
if flag(dev)
ghc-options: -Wmissed-specialisations
-Wall-missed-specialisations
if flag(dev) || flag(debug)
ghc-options: -fno-ignore-asserts
if impl(ghc >= 8.0)
ghc-options: -Wcompat
-Wunrecognised-warning-flags
-Widentities
-Wincomplete-record-updates
-Wincomplete-uni-patterns
-Wredundant-constraints
-Wnoncanonical-monad-instances
common optimization-options
ghc-options: -O2
-fdicts-strict
-fspec-constr-recursive=16
-fmax-worker-args=16
if flag(fusion-plugin) && !impl(ghcjs) && !impl(ghc < 8.6)
ghc-options: -fplugin Fusion.Plugin
-- We need optimization options here to optimize internal (non-inlined)
-- versions of functions. Also, we have some benchmarking inspection tests
-- part of the library when built with --benchmarks flag. Thos tests fail
-- if we do not use optimization options here. It was observed that due to
-- -O2 here some concurrent/nested benchmarks improved and others regressed.
-- We can investigate a bit more here why the regression occurred.
common lib-options
import: compile-options, optimization-options
common bench-depends
build-depends:
-- Core libraries shipped with ghc, the min and max
-- constraints of these libraries should match with
-- the GHC versions we support
base >= 4.8 && < 5
, deepseq >= 1.4.1 && < 1.5
, mtl >= 2.2 && < 3
-- other libraries
, streamly >= 0.7.0
, random >= 1.0 && < 2.0
, gauge >= 0.2.4 && < 0.3
, transformers >= 0.4 && < 0.6
if flag(fusion-plugin) && !impl(ghcjs) && !impl(ghc < 8.6)
build-depends:
fusion-plugin >= 0.2 && < 0.3
if flag(inspection)
build-depends: template-haskell >= 2.14 && < 2.17
, inspection-testing >= 0.4 && < 0.5
, ghc-prim >= 0.2 && < 0.7
-- Array uses a Storable constraint in dev build making several inspection
-- tests fail
if flag(dev) && flag(inspection)
build-depends: inspection-and-dev-flags-cannot-be-used-together
-------------------------------------------------------------------------------
-- Library
-------------------------------------------------------------------------------
library
import: lib-options, bench-depends
hs-source-dirs: lib
exposed-modules: Streamly.Benchmark.Common
, Streamly.Benchmark.Prelude
-------------------------------------------------------------------------------
-- Benchmarks
-------------------------------------------------------------------------------
-- Whatever stack size below 32K we use GHC seems to report the stack size as
-- 32K at crash. Even K0K works. Therefore it probably does not make sense to
-- set it to lower than 32K.
common bench-options
import: compile-options, optimization-options, bench-depends
ghc-options: -rtsopts
build-depends: streamly-benchmarks == 0.0.0
-- Some benchmarks are threaded some are not
common bench-options-threaded
import: compile-options, optimization-options, bench-depends
-- -threaded and -N2 is important because some GC and space leak issues
-- trigger only with these options.
ghc-options: -threaded -rtsopts -with-rtsopts "-N2"
build-depends: streamly-benchmarks == 0.0.0
-------------------------------------------------------------------------------
-- Serial Streams
-------------------------------------------------------------------------------
benchmark Prelude.Serial
import: bench-options
type: exitcode-stdio-1.0
hs-source-dirs: Streamly/Benchmark/Prelude
main-is: Serial.hs
if impl(ghcjs)
buildable: False
else
buildable: True
benchmark Prelude.WSerial
import: bench-options
type: exitcode-stdio-1.0
hs-source-dirs: Streamly/Benchmark/Prelude
main-is: WSerial.hs
if impl(ghcjs)
buildable: False
else
buildable: True
benchmark Prelude.ZipSerial
import: bench-options
type: exitcode-stdio-1.0
hs-source-dirs: Streamly/Benchmark/Prelude
main-is: ZipSerial.hs
if impl(ghcjs)
buildable: False
else
buildable: True
benchmark Prelude.ZipAsync
import: bench-options
type: exitcode-stdio-1.0
hs-source-dirs: Streamly/Benchmark/Prelude
main-is: ZipAsync.hs
if impl(ghcjs)
buildable: False
else
buildable: True
benchmark Prelude.Ahead
import: bench-options-threaded
type: exitcode-stdio-1.0
hs-source-dirs: Streamly/Benchmark/Prelude
main-is: Ahead.hs
if impl(ghcjs)
buildable: False
else
buildable: True
benchmark Prelude.Async
import: bench-options-threaded
type: exitcode-stdio-1.0
hs-source-dirs: Streamly/Benchmark/Prelude
main-is: Async.hs
if impl(ghcjs)
buildable: False
else
buildable: True
benchmark Prelude.WAsync
import: bench-options-threaded
type: exitcode-stdio-1.0
hs-source-dirs: Streamly/Benchmark/Prelude
main-is: WAsync.hs
if impl(ghcjs)
buildable: False
else
buildable: True
benchmark Prelude.Parallel
import: bench-options-threaded
type: exitcode-stdio-1.0
hs-source-dirs: Streamly/Benchmark/Prelude
main-is: Parallel.hs
if impl(ghcjs)
buildable: False
else
buildable: True
benchmark Data.Unfold
import: bench-options
type: exitcode-stdio-1.0
hs-source-dirs: .
main-is: Streamly/Benchmark/Data/Unfold.hs
other-modules: Streamly.Benchmark.Data.NestedUnfoldOps
if impl(ghcjs)
buildable: False
else
buildable: True
benchmark Data.Fold
import: bench-options
type: exitcode-stdio-1.0
hs-source-dirs: Streamly/Benchmark/Data
main-is: Fold.hs
if impl(ghcjs)
buildable: False
else
buildable: True
benchmark Data.Parser.ParserD
import: bench-options
type: exitcode-stdio-1.0
hs-source-dirs: Streamly/Benchmark/Data/Parser
main-is: ParserD.hs
if impl(ghcjs)
buildable: False
else
buildable: True
build-depends: exceptions >= 0.8 && < 0.11
benchmark Data.Parser.ParserK
import: bench-options
type: exitcode-stdio-1.0
hs-source-dirs: Streamly/Benchmark/Data/Parser
main-is: ParserK.hs
if impl(ghcjs)
buildable: False
else
buildable: True
build-depends: exceptions >= 0.8 && < 0.11
benchmark Data.Parser
import: bench-options
type: exitcode-stdio-1.0
hs-source-dirs: Streamly/Benchmark/Data
main-is: Parser.hs
if impl(ghcjs)
buildable: False
else
buildable: True
build-depends: exceptions >= 0.8 && < 0.11
-------------------------------------------------------------------------------
-- Raw Streams
-------------------------------------------------------------------------------
benchmark Data.Stream.StreamD
import: bench-options
type: exitcode-stdio-1.0
hs-source-dirs: Streamly/Benchmark/Data/Stream
main-is: StreamD.hs
if impl(ghcjs)
buildable: False
else
buildable: True
benchmark Data.Stream.StreamK
import: bench-options
type: exitcode-stdio-1.0
hs-source-dirs: Streamly/Benchmark/Data/Stream
main-is: StreamK.hs
if impl(ghcjs)
buildable: False
else
buildable: True
benchmark Data.Stream.StreamDK
import: bench-options
type: exitcode-stdio-1.0
hs-source-dirs: Streamly/Benchmark/Data/Stream
main-is: StreamDK.hs
if impl(ghcjs)
buildable: False
else
buildable: True
executable nano-bench
import: bench-options
hs-source-dirs: .
main-is: NanoBenchmarks.hs
if flag(dev)
buildable: True
else
buildable: False
-------------------------------------------------------------------------------
-- Concurrent Streams
-------------------------------------------------------------------------------
benchmark Prelude.Concurrent
import: bench-options-threaded
type: exitcode-stdio-1.0
hs-source-dirs: Streamly/Benchmark/Prelude
main-is: Concurrent.hs
benchmark Prelude.Adaptive
import: bench-options-threaded
type: exitcode-stdio-1.0
hs-source-dirs: Streamly/Benchmark/Prelude
main-is: Adaptive.hs
if impl(ghcjs)
buildable: False
else
buildable: True
benchmark Prelude.Rate
import: bench-options-threaded
type: exitcode-stdio-1.0
hs-source-dirs: Streamly/Benchmark/Prelude
main-is: Rate.hs
if impl(ghcjs)
buildable: False
else
buildable: True
-------------------------------------------------------------------------------
-- Array Benchmarks
-------------------------------------------------------------------------------
benchmark Data.Array
import: bench-options
type: exitcode-stdio-1.0
hs-source-dirs: .
main-is: Streamly/Benchmark/Data/Array.hs
other-modules: Streamly.Benchmark.Data.ArrayOps
benchmark Data.Prim.Array
import: bench-options
type: exitcode-stdio-1.0
hs-source-dirs: .
main-is: Streamly/Benchmark/Data/Prim/Array.hs
other-modules: Streamly.Benchmark.Data.Prim.ArrayOps
benchmark Data.SmallArray
import: bench-options
type: exitcode-stdio-1.0
hs-source-dirs: .
main-is: Streamly/Benchmark/Data/SmallArray.hs
other-modules: Streamly.Benchmark.Data.SmallArrayOps
benchmark Memory.Array
import: bench-options
type: exitcode-stdio-1.0
hs-source-dirs: .
main-is: Streamly/Benchmark/Memory/Array.hs
other-modules: Streamly.Benchmark.Memory.ArrayOps
-------------------------------------------------------------------------------
-- FileIO Benchmarks
-------------------------------------------------------------------------------
benchmark fileio
import: bench-options
type: exitcode-stdio-1.0
hs-source-dirs: .
main-is: FileIO.hs
other-modules: Streamly.Benchmark.FileIO.Array
, Streamly.Benchmark.FileIO.Stream
build-depends:
typed-process >= 0.2.3 && < 0.3
-------------------------------------------------------------------------------
-- benchmark comparison and presentation
-------------------------------------------------------------------------------
executable chart
default-language: Haskell2010
ghc-options: -Wall
hs-source-dirs: .
main-is: Chart.hs
if flag(dev) && !flag(no-charts) && !impl(ghcjs)
buildable: True
build-Depends:
base >= 4.8 && < 5
, bench-show >= 0.3 && < 0.4
, transformers >= 0.4 && < 0.6
else
buildable: False