#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
#
# Author: Steve Sistare <steven.sistare@oracle.com>
#
# Usage: runmany <repeat> command args ...
#   Run command <repeat> 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