3SCRIPT_DIR=$(cd `dirname $0`; pwd)
6source $SCRIPT_DIR/build-lib.sh
10 echo " [--benchmarks <"bench1 bench2 ..." | help>]"
11 echo " [--fields <"field1 field2 ..." | help>]"
13 echo " [--no-measure]"
20 echo " [--with-compiler <compiler exe name>]"
21 echo " [--cabal-build-options <options>]"
22 echo " [--rtsopts <opts>]"
23 echo " [--compare] [--base <commit>] [--candidate <commit>]"
24 echo " -- <gauge options or benchmarks>"
26 echo "--benchmarks: benchmarks to run, use 'help' for list of benchmarks"
27 echo "--fields: measurement fields to report, use 'help' for a list"
28 echo "--graphs: Generate graphical reports"
29 echo "--no-measure: Don't run benchmarks, run reports from previous results"
30 echo "--append: Don't overwrite previous results, append for comparison"
31 echo "--long: Use much longer stream size for infinite stream benchmarks"
32 echo "--slow: Slightly more accurate results at the expense of speed"
33 echo "--quick: Faster results, useful for longer benchmarks"
34 echo "--raw: Run the benchmarks but don't report them. This is useful when"
35 echo " you only want to work with the csv files generated."
36 echo "--cabal-build-options: Pass any cabal build options to be used for build"
37 echo " e.g. --cabal-build-options \"--flag dev\""
39 echo "When specific space complexity group is chosen then (and only then) "
40 echo "RTS memory restrictions are used accordingly. For example, "
41 echo "bench.sh --benchmarks Data.Parser -- Data.Parser/o-1-space "
42 echo "restricts Heap/Stack space for O(1) characterstics"
44 echo "When using --compare, by default comparative chart of HEAD^ vs HEAD"
45 echo "commit is generated, in the 'charts' directory."
46 echo "Use --base and --candidate to select the commits to compare."
48 echo "Any arguments after a '--' are passed directly to gauge"
52#-----------------------------------------------------------------------------
53# Reporting utility functions
54#-----------------------------------------------------------------------------
57 echo "Comparison groups:"
67# chart is expensive to build and usually not required to be rebuilt,
68# use master branch as fallback
70 local path=$(cabal_which streamly-benchmarks x $1)
73 cabal_which_builddir dist-newstyle streamly-benchmarks x $1
80 local prog_name="chart"
82 local prog_path=$(cabal_which_report $prog_name)
83 if test -x "$prog_path"
92 local prog_name="chart"
93 local prog_path=$(cabal_which_report $prog_name)
96 if test ! -x "$prog_path" -a "$BUILD_ONCE" = "0"
98 echo "Building bench-show executables"
100 $CABAL_EXECUTABLE v2-build --flags dev chart \
101 || die "bench-show build failed"
103 elif test ! -x "$prog_path"
110build_report_progs() {
113 build_report_prog || exit 1
115 prog=$(find_report_prog) || \
116 die "Cannot find bench-show executable"
117 echo "Using bench-show executable [$prog]"
121# We run the benchmarks in isolation in a separate process so that different
122# benchmarks do not interfere with other. To enable that we need to pass the
123# benchmark exe path to gauge as an argument. Unfortunately it cannot find its
126# The path is dependent on the architecture and cabal version.
130 echo "charts/$bench_name/results.csv"
133# --min-duration 0 means exactly one iteration per sample. We use a million
134# iterations in the benchmarking code explicitly and do not use the iterations
135# done by the benchmarking tool.
137# Benchmarking tool by default discards the first iteration to remove
138# aberrations due to initial evaluations etc. We do not discard it because we
139# are anyway doing iterations in the benchmarking code and many of them so that
140# any constant factor gets amortized and anyway it is a cost that we pay in
143# We can pass --min-samples value from the command line as second argument
144# after the benchmark name in case we want to use more than one sample.
147# $2: bench executable
148target_exe_extra_args () {
152 local output_file=$(bench_output_file $bench_name)
153 mkdir -p `dirname $output_file`
155 local QUICK_OPTS="--quick --min-duration 0"
157 if test "$LONG" -eq 0
159 if test "$SLOW" -eq 0
161 if test "$QUICK_MODE" -eq 0
163 # default mode, not super quick, not slow
164 SPEED_OPTIONS="$QUICK_OPTS --min-samples 10 --time-limit 1"
166 # super quick but less accurate
167 # When the time-limit is too low and the benchmark is tiny,
168 # then if the number of iterations is very small the GC stats
169 # may remain 0. So keep the time-limit at a minimum of 10 ms
170 # to collect significant stats. The problem was observed in
171 # the Prelude.Serial/reverse' benchmark.
172 SPEED_OPTIONS="$QUICK_OPTS --time-limit 0.01 --include-first-iter"
175 # Slow but more accurate mode
176 SPEED_OPTIONS="--min-duration 0"
179 # large stream size, always super quick
180 GAUGE_ARGS="$GAUGE_ARGS $bench_name/o-1-space"
181 SPEED_OPTIONS="--stream-size 10000000 $QUICK_OPTS --include-first-iter"
184 echo "$SPEED_OPTIONS \
185 --csvraw=$output_file \
187 --measure-with "$SCRIPT_DIR/bench-exec-one.sh" \
191run_benches_comparing() {
194 if test -z "$CANDIDATE"
196 CANDIDATE=$(git rev-parse HEAD)
200 # XXX Should be where the current branch is forked from master
203 echo "Comparing baseline commit [$BASE] with candidate [$CANDIDATE]"
204 echo "Checking out base commit [$BASE] for benchmarking"
205 git checkout "$BASE" || die "Checkout of base commit [$BASE] failed"
207 $BUILD_BENCH || die "build failed"
208 run_targets streamly-benchmarks b "$bench_list" target_exe_extra_args
210 echo "Checking out candidate commit [$CANDIDATE] for benchmarking"
211 git checkout "$CANDIDATE" || \
212 die "Checkout of candidate [$CANDIDATE] commit failed"
214 $BUILD_BENCH || die "build failed"
215 run_targets streamly-benchmarks b "$bench_list" target_exe_extra_args
216 # XXX reset back to the original commit
219backup_output_file() {
221 local output_file=$(bench_output_file $bench_name)
223 if test -e $output_file -a "$APPEND" != 1
225 mv -f -v $output_file ${output_file}.prev
234 backup_output_file $i
237 if test "$COMPARE" = "0"
239 run_targets streamly-benchmarks b "$bench_list" target_exe_extra_args
241 run_benches_comparing "$bench_list"
247 prog=$(find_report_prog) || \
248 die "Cannot find bench-graph executable"
253 echo "Generating reports for ${i}..."
254 $prog $(test "$GRAPH" = 1 && echo "--graphs") \
255 --benchmark $i --fields "$FIELDS"
259#-----------------------------------------------------------------------------
260# Execution starts here
261#-----------------------------------------------------------------------------
268DEFAULT_FIELDS="allocated bytescopied cputime"
269ALL_FIELDS="$FIELDS time cycles utime stime minflt majflt nvcsw nivcsw"
270FIELDS=$DEFAULT_FIELDS
285CABAL_BUILD_OPTIONS="--flag fusion-plugin "
287#-----------------------------------------------------------------------------
289#-----------------------------------------------------------------------------
294 -h|--help|help) print_help ;;
295 # options with arguments
296 --benchmarks) shift; TARGETS=$1; shift ;;
297 --targets) shift; TARGETS=$1; shift ;;
298 --fields) shift; FIELDS=$1; shift ;;
299 --base) shift; BASE=$1; shift ;;
300 --candidate) shift; CANDIDATE=$1; shift ;;
301 --with-compiler) shift; CABAL_WITH_COMPILER=$1; shift ;;
302 --cabal-build-flags) shift; CABAL_BUILD_OPTIONS+=$1; shift ;;
303 --cabal-build-options) shift; CABAL_BUILD_OPTIONS+=$1; shift ;;
304 --rtsopts) shift; RTS_OPTIONS=$1; shift ;;
306 --slow) SLOW=1; shift ;;
307 --quick) QUICK_MODE=1; shift ;;
308 --compare) COMPARE=1; shift ;;
309 --raw) RAW=1; shift ;;
310 --append) APPEND=1; shift ;;
311 --long) LONG=1; shift ;;
312 --graphs) GRAPH=1; shift ;;
313 --no-measure) MEASURE=0; shift ;;
314 --dev-build) RUNNING_DEVBUILD=1; shift ;;
316 -*|--*) echo "Unknown flags: $*"; echo; print_help ;;
324#-----------------------------------------------------------------------------
326#-----------------------------------------------------------------------------
328only_real_benchmarks () {
332 for j in $COMPARISONS
339 if test "$SKIP" -eq 0
346# Requires RUNNING_DEVBUILD var
347source $SCRIPT_DIR/targets.sh
349if test "$(has_item "$TARGETS" help)" = "help"
357if test "$(has_item "$FIELDS" help)" = "help"
359 echo "Supported fields: $ALL_FIELDS"
360 echo "Default fields: $DEFAULT_FIELDS"
366 if test -n "$TARGETS"
368 echo "Cannot specify benchmarks [$TARGETS] with --long"
371 TARGETS=$infinite_grp
374DEFAULT_TARGETS="$(all_grp)"
375TARGETS=$(set_targets)
378TARGETS=$(only_real_benchmarks)
380echo "Using benchmark suites [$TARGETS]"
382#-----------------------------------------------------------------------------
383# Build reporting utility
384#-----------------------------------------------------------------------------
386# We need to build the report progs first at the current (latest) commit before
387# checking out any other commit for benchmarking.
390#-----------------------------------------------------------------------------
391# Build and run targets
392#-----------------------------------------------------------------------------
394BUILD_BENCH="$CABAL_EXECUTABLE v2-build $CABAL_BUILD_OPTIONS --enable-benchmarks"
395if test "$MEASURE" = "1"
397 run_build "$BUILD_BENCH" streamly-benchmarks bench "$TARGETS"
400 run_measurements "$TARGETS"
403#-----------------------------------------------------------------------------
405#-----------------------------------------------------------------------------
410 if test "$(has_item "$TARGETS_ORIG" $i)" = $i
412 COMPARISON_REPORTS="$COMPARISON_REPORTS $i"
414 constituents=$(eval "echo -n \$${i}")
415 dest_file="charts/$i/results.csv"
417 for j in $constituents
419 cat "charts/$j/results.csv" >> $dest_file
426 run_reports "$TARGETS"
427 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