packages feed

streaming-benchmarks-0.1.0: run.sh

#!/bin/bash

print_help () {
  echo "Usage: $0 [--quick] [--pedantic] [--no-graph] [--no-measure] <benchmark-name or prefix> [min-samples]"
  echo "Any arguments after a '--' will be passed as it is to guage"
  exit
}

# $1: message
die () {
  >&2 echo -e "Error: $1"
  exit 1
}

while test -n "$1"
do
  case $1 in
    -h|--help|help) print_help ;;
    --quick) QUICK=1; shift ;;
    --pedantic) PEDANTIC=1; shift ;;
    --no-graph) GRAPH=0; shift ;;
    --no-measure) MEASURE=0; shift ;;
    --) shift; break ;;
    -*|--*) print_help ;;
    *) break ;;
  esac
done

STACK=stack
if test "$PEDANTIC" = "1"
then
  GHC_PATH=`$STACK path --compiler-bin`
  export PATH=$GHC_PATH:$PATH
  mkdir -p .stack-root
  export STACK_ROOT=`pwd`/.stack-root
  STACK="$STACK --system-ghc --stack-yaml stack-pedantic.yaml"
fi

echo "Using stack command [$STACK]"
$STACK build --bench --no-run-benchmarks || die "build failed"

# We run the benchmarks in isolation in a separate process so that different
# benchmarks do not interfere with other. To enable that we need to pass the
# benchmark exe path to guage as an argument. Unfortunately it cannot find its
# own path currently.

# The path is dependent on the architecture and cabal version.
# Use this command to find the exe if this script fails with an error:
# find .stack-work/ -type f -name "benchmarks"

enable_isolated () {
  local PROG=`$STACK path --dist-dir`/build/benchmarks/benchmarks
  if test -x "$PROG"
  then
    BENCH_PROG="--measure-with $PROG"
  else
    echo
    echo "WARNING! benchmark binary [$PROG] not found or not executable"
    echo "WARNING! not using isolated measurement."
    echo
  fi
}

enable_isolated

# --min-duration 0 means exactly one iteration per sample. We use a million
# iterations in the benchmarking code explicitly and do not use the iterations
# done by the benchmarking tool.
#
# Benchmarking tool by default discards the first iteration to remove
# aberrations due to initial evaluations etc. We do not discard it because we
# are anyway doing iterations in the benchmarking code and many of them so that
# any constant factor gets amortized and anyway it is a cost that we pay in
# real life.
#
# We can pass --min-samples value from the command line as second argument
# after the benchmark name in case we want to use more than one sample.

if test "$QUICK" = "1"
then
  ENABLE_QUICK="--quick"
fi

if test "$MEASURE" != "0"
  then
  if test -e results.csv
  then
    mv -f -v results.csv results.csv.prev
  fi

  # We set min-samples to 1 so that we run with default benchmark duration of 5
  # seconds, whatever number of samples are possible in that.
  # We run just one iteration for each sample. Anyway the default is to run
  # for 30 ms and most our benchmarks are close to that or more.
  $STACK bench --benchmark-arguments "$ENABLE_QUICK \
    --include-first-iter \
    --min-samples 1 \
    --min-duration 0 \
    --csv=results.csv \
    -v 2 \
    $BENCH_PROG $*" || die "Benchmarking failed"
fi

if test "$GRAPH" != "0"
then
  echo
  echo "Generating charts from results.csv..."
  $STACK exec makecharts results.csv
fi