#!/bin/sh # SPDX-License-Identifier: GPL-2.0 # # Author: Steve Sistare # # Usage: runmany command args ... # Run command times, extract time, and print average and stdev. # # Command must print a line of the form "Time %f" (eg, like hackbench). # Convert float $1 to integral fixed-point value with $2 decimal places. # ftoi() { declare -i tens=10**$2 echo $(echo "scale=0; ($tens * $1) / 1" | bc -q) } # Convert integral fixed-point $1 with $2 decimal places to floating # point string. # itof() { declare -i i frac tens x=$1 [[ $x -lt 0 ]] && sign='-' x=(-$x) tens=10**$2 i=$x/tens frac=$x%tens printf "%s%d.%0${2}d" "$sign" $i $frac } # Return the average of all arguments. # average() { declare -i x avg=0 for x in $* ; do avg=avg+x done avg=avg/$# echo $avg } # Return the stdev of all args, as a percent of the average, as a float with # 6 decimal places. # stdev() { declare -i x var=0 declare -i avg=$(average $@) for x in $* ; do x=x-avg var=var+x*x done echo "scale=6; sqrt($var / ($# - 1)) * 100 / $avg" | bc -q } declare -i n=$1 declare -a -i t if [[ $n -eq 0 ]] ; then echo "usage: runmany num command args ..." exit 1 fi cmd="${@:2:$#}" for ((i=0; i<$n; i=i+1)) ; do t1=$($cmd | grep Time | awk '{print $2}') t[$i]=$(ftoi $t1 3) printf "%6.3f " $t1 done avg=$(average ${t[*]}) favg=$(itof avg 3) std=$(stdev ${t[*]}) printf " Average %.3f stdev %.1f%%\n" $favg $std