#!/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