3#------------------------------------------------------------------------------
5#------------------------------------------------------------------------------
7# IMPORTANT NOTE: the names "_grp" and "_cmp" suffixes are special, do
8# not rename them to something else.
20prelude_concurrent_grp="\
37 Data.Array.Prim.Pinned"
39base_parser_grp="Data.Parser.ParserD Data.Parser.ParserK"
40parser_grp="Data.Fold Data.Parser"
42#------------------------------------------------------------------------------
43# Streaming vs non-streaming
44#------------------------------------------------------------------------------
45# The "o-1-space" groups of these benchmarks are run with long stream
46# sizes when --long option is used.
50 $prelude_concurrent_grp \
53#------------------------------------------------------------------------------
55#------------------------------------------------------------------------------
56# *_cmp denotes a comparison benchmarks, the benchmarks provided in *_cmp
57# variables are compared with each other
58base_stream_cmp="Data.Stream.StreamD Data.Stream.StreamK"
59serial_wserial_cmp="Prelude.Serial Prelude.WSerial"
60serial_async_cmp="Prelude.Serial Prelude.Async"
61concurrent_cmp="Prelude.Async Prelude.WAsync Prelude.Ahead Prelude.Parallel"
62array_cmp="Memory.Array Data.Array.Prim Data.Array Data.Array.Prim.Pinned"
63pinned_array_cmp="Memory.Array Data.Array.Prim.Pinned"
64base_parser_cmp=$base_parser_grp
74#------------------------------------------------------------------------------
76#------------------------------------------------------------------------------
77# All high level benchmarks
80 $prelude_concurrent_grp \
89 prelude_concurrent_grp \
95#------------------------------------------------------------------------------
97#------------------------------------------------------------------------------
99BENCH_SH_DIR=$(dirname $0)
102 echo "Individual benchmarks:"
110list_bench_groups () {
111 echo "Benchmark groups:"
112 for i in $ALL_BENCH_GROUPS
122 echo "Comparison groups:"
123 for i in $COMPARISONS
134 echo " [--benchmarks <"bench1 bench2 ..." | help>]"
135 echo " [--fields <"field1 field2 ..." | help>]"
137 echo " [--no-measure]"
142 echo " [--cabal-build-flags <flag>]"
143 echo " [--compare] [--base <commit>] [--candidate <commit>]"
144 echo " -- <gauge options or benchmarks>"
146 echo "--benchmarks: benchmarks to run, use 'help' for list of benchmarks"
147 echo "--fields: measurement fields to report, use 'help' for a list"
148 echo "--graphs: Generate graphical reports"
149 echo "--no-measure: Don't run benchmarks, run reports from previous results"
150 echo "--append: Don't overwrite previous results, append for comparison"
151 echo "--long: Use much longer stream size for infinite stream benchmarks"
152 echo "--slow: Slightly more accurate results at the expense of speed"
153 echo "--quick: Faster results, useful for longer benchmarks"
154 echo "--cabal-build-flags: Pass any cabal builds flags to be used for build"
156 echo "When specific space complexity group is chosen then (and only then) "
157 echo "RTS memory restrictions are used accordingly. For example, "
158 echo "bench.sh --benchmarks Data.Parser -- Data.Parser/o-1-space "
159 echo "restricts Heap/Stack space for O(1) characterstics"
161 echo "When using --compare, by default comparative chart of HEAD^ vs HEAD"
162 echo "commit is generated, in the 'charts' directory."
163 echo "Use --base and --candidate to select the commits to compare."
165 echo "Any arguments after a '--' are passed directly to gauge"
171 >&2 echo -e "Error: $1"
176 if test -z "$BENCHMARKS"
178 echo $DEFAULT_BENCHMARKS
180 for i in $(echo $BENCHMARKS)
183 *_grp) eval "echo -n \$${i}" ;;
184 *_cmp) eval "echo -n \$${i} $i" ;;
193 local prog_name="chart"
195 local prog_path=$($WHICH_COMMAND $prog_name)
196 if test -x "$prog_path"
205 local prog_name="chart"
206 local prog_path=$($WHICH_COMMAND $prog_name)
209 if test ! -x "$prog_path" -a "$BUILD_ONCE" = "0"
211 echo "Building bench-graph executables"
213 $BUILD_CHART_EXE || die "build failed"
214 elif test ! -x "$prog_path"
221build_report_progs() {
224 build_report_prog || exit 1
226 prog=$(find_report_prog) || \
227 die "Cannot find bench-graph executable"
228 echo "Using bench-graph executable [$prog]"
232# We run the benchmarks in isolation in a separate process so that different
233# benchmarks do not interfere with other. To enable that we need to pass the
234# benchmark exe path to gauge as an argument. Unfortunately it cannot find its
237# The path is dependent on the architecture and cabal version.
238# Use this command to find the exe if this script fails with an error:
239# find .stack-work/ -type f -name "benchmarks"
243 local bench_prog=`stack path --dist-dir`/build/$bench_name/$bench_name
244 if test -x "$bench_prog"
254 local bench_prog=`$WHICH_COMMAND $1`
255 if test -x "$bench_prog"
265 echo "charts/$bench_name/results.csv"
269function run_verbose() {
274# --min-duration 0 means exactly one iteration per sample. We use a million
275# iterations in the benchmarking code explicitly and do not use the iterations
276# done by the benchmarking tool.
278# Benchmarking tool by default discards the first iteration to remove
279# aberrations due to initial evaluations etc. We do not discard it because we
280# are anyway doing iterations in the benchmarking code and many of them so that
281# any constant factor gets amortized and anyway it is a cost that we pay in
284# We can pass --min-samples value from the command line as second argument
285# after the benchmark name in case we want to use more than one sample.
289 local bench_exe=$bench_name
290 local output_file=$(bench_output_file $bench_name)
292 bench_prog=$($GET_BENCH_PROG $bench_exe) || \
293 die "Cannot find benchmark executable for benchmark $bench_name"
295 mkdir -p `dirname $output_file`
297 echo "Running benchmark $bench_name ..."
299 local QUICK_OPTS="--quick --min-duration 0"
301 if test "$LONG" -eq 0
303 if test "$SLOW" -eq 0
306 if test "$QUICK_MODE" -eq 0
308 # default mode, not super quick, not slow
309 SPEED_OPTIONS="$QUICK_OPTS --min-samples 10 --time-limit 1"
311 # super quick but less accurate
312 SPEED_OPTIONS="$QUICK_OPTS --time-limit 0 --include-first-iter"
315 # Slow but more accurate mode
316 SPEED_OPTIONS="--min-duration 0"
319 # large stream size, always super quick
320 GAUGE_ARGS="$GAUGE_ARGS $bench_name/o-1-space"
321 SPEED_OPTIONS="--stream-size 10000000 $QUICK_OPTS --include-first-iter"
324 export BENCH_EXEC_PATH=$bench_prog
326 run_verbose $bench_prog $SPEED_OPTIONS \
327 --csvraw=$output_file \
329 --measure-with "$BENCH_SH_DIR/bin/bench-exec-one.sh" \
330 $GAUGE_ARGS || die "Benchmarking failed"
340run_benches_comparing() {
343 if test -z "$CANDIDATE"
345 CANDIDATE=$(git rev-parse HEAD)
349 # XXX Should be where the current branch is forked from master
352 echo "Comparing baseline commit [$BASE] with candidate [$CANDIDATE]"
353 echo "Checking out base commit [$BASE] for benchmarking"
354 git checkout "$BASE" || die "Checkout of base commit [$BASE] failed"
356 $BUILD_BENCH || die "build failed"
357 run_benches "$bench_list"
359 echo "Checking out candidate commit [$CANDIDATE] for benchmarking"
360 git checkout "$CANDIDATE" || \
361 die "Checkout of candidate [$CANDIDATE] commit failed"
363 $BUILD_BENCH || die "build failed"
364 run_benches "$bench_list"
365 # XXX reset back to the original commit
368backup_output_file() {
370 local output_file=$(bench_output_file $bench_name)
372 if test -e $output_file -a "$APPEND" != 1
374 mv -f -v $output_file ${output_file}.prev
383 backup_output_file $i
386 if test "$COMPARE" = "0"
388 run_benches "$bench_list"
390 run_benches_comparing "$bench_list"
396 prog=$(find_report_prog) || \
397 die "Cannot find bench-graph executable"
402 echo "Generating reports for ${i}..."
403 $prog $(test "$GRAPH" = 1 && echo "--graphs") \
404 --benchmark $i --fields "$FIELDS"
408#-----------------------------------------------------------------------------
409# Execution starts here
410#-----------------------------------------------------------------------------
412DEFAULT_BENCHMARKS="$all_grp"
413DEFAULT_FIELDS="allocated bytescopied cputime"
414ALL_FIELDS="$FIELDS time cycles utime stime minflt majflt nvcsw nivcsw"
415FIELDS=$DEFAULT_FIELDS
435GHC_VERSION=$(ghc --numeric-version)
438 find dist-newstyle -type f -path "*${GHC_VERSION}/streamly-benchmarks*/$1"
441#-----------------------------------------------------------------------------
443#-----------------------------------------------------------------------------
448 -h|--help|help) print_help ;;
449 # options with arguments
450 --benchmarks) shift; BENCHMARKS=$1; shift ;;
451 --fields) shift; FIELDS=$1; shift ;;
452 --base) shift; BASE=$1; shift ;;
453 --candidate) shift; CANDIDATE=$1; shift ;;
454 --cabal-build-flags) shift; CABAL_BUILD_FLAGS=$1; shift ;;
455 --rtsopts) shift; RTS_OPTIONS=$1; shift ;;
457 --slow) SLOW=1; shift ;;
458 --quick) QUICK_MODE=1; shift ;;
459 --compare) COMPARE=1; shift ;;
460 --raw) RAW=1; shift ;;
461 --append) APPEND=1; shift ;;
462 --long) LONG=1; shift ;;
463 --graphs) GRAPH=1; shift ;;
464 --no-measure) MEASURE=0; shift ;;
466 -*|--*) echo "Unknown flags: $*"; echo; print_help ;;
472only_real_benchmarks () {
476 for j in $COMPARISONS
483 if test "$SKIP" -eq 0
501BENCHMARKS_ORIG=$BENCHMARKS
502if test "$(has_item "$BENCHMARKS_ORIG" help)" = "help"
510if test "$(has_item "$FIELDS" help)" = "help"
512 echo "Supported fields: $ALL_FIELDS"
513 echo "Default fields: $DEFAULT_FIELDS"
519 if test -n "$BENCHMARKS"
521 echo "Cannot specify benchmarks [$BENCHMARKS] with --long"
524 BENCHMARKS=$infinite_grp
527BENCHMARKS=$(set_benchmarks)
528BENCHMARKS_ORIG=$BENCHMARKS
529BENCHMARKS=$(only_real_benchmarks)
530EXECUTABLES=$BENCHMARKS
532echo "Using benchmark suites [$BENCHMARKS]"
534if test "$USE_STACK" = "1"
536 WHICH_COMMAND="stack exec which"
537 BUILD_CHART_EXE="stack build --flag streamly:dev"
538 GET_BENCH_PROG=stack_bench_prog
539 BUILD_BENCH="stack build $STACK_BUILD_FLAGS --bench --no-run-benchmarks"
541 # XXX cabal issue "cabal v2-exec which" cannot find benchmark/test executables
542 #WHICH_COMMAND="cabal v2-exec which"
543 WHICH_COMMAND=cabal_which
544 BUILD_CHART_EXE="cabal v2-build --flags dev chart"
545 GET_BENCH_PROG=cabal_bench_prog
546 BUILD_BENCH="cabal v2-build $CABAL_BUILD_FLAGS --enable-benchmarks"
549#-----------------------------------------------------------------------------
551#-----------------------------------------------------------------------------
553# We need to build the report progs first at the current (latest) commit before
554# checking out any other commit for benchmarking.
555build_report_progs "$BENCHMARKS"
557#-----------------------------------------------------------------------------
559#-----------------------------------------------------------------------------
561if test "$MEASURE" = "1"
564 if test "$USE_STACK" = "1"
566 $BUILD_BENCH || die "build failed"
568 $BUILD_BENCH $EXECUTABLES || die "build failed"
570 run_measurements "$BENCHMARKS"
573#-----------------------------------------------------------------------------
575#-----------------------------------------------------------------------------
580 if test "$(has_item "$BENCHMARKS_ORIG" $i)" = $i
582 COMPARISON_REPORTS="$COMPARISON_REPORTS $i"
584 constituents=$(eval "echo -n \$${i}")
585 dest_file="charts/$i/results.csv"
587 for j in $constituents
589 cat "charts/$j/results.csv" >> $dest_file
596 run_reports "$BENCHMARKS"
597 run_reports "$COMPARISON_REPORTS"
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list