Ksh benchmark tests

function repeatloop {
  integer i=0
#dies with empty repeat loop, so use 'while'
  while (( i < $1 ))
  do
    ((i++))
  done
}

function ifact1loop {
  integer i
  for (( i = 0; i < $1; i++ ))
  do
    float fact=1
    integer j;
    for (( j = 0; j < 101; j++ ))
    do
      ((fact *= j))
    done
  done
}

function ifact2loop {
  integer i
  for (( i = 0; i < $1; i++ ))
  do
    integer j=1
    float fact
    integer j;
    for (( j = 0; j < 101; j++ ))
    do
      if ((j <= 1))
      then fact=1
      else ((fact *= j))
      fi
    done
  done
}

# Another gremlin, after typedef float, when using the variable 
# in an expression leaving out the $ works, bug putting it in
# causes a trunc to float and a "print" error
#    float x=$1
#    print $(( x * $(fact $(( x - 1 )) ) ))
#    print $(( $x * $(fact $(( $x - 1 )) ) ))
function fact {
  if (( $1 <= 1 ))
  then print 1
  else print $(( $1 * $(fact $(( $1 - 1 )) ) ))
  fi
}

function factloop {
  integer i
  for (( i = 0; i < $1; i++ ))
  do
# passing 100 as an integer causes truncation at overflow!
    float x=$(fact 100.000000001)
  done
}

# this routine doesn't do what the Tcl and MetaCard 
# equivalents do because ksh doesn't have a sort function
function stems {
  integer n nwords
  typeset w lastfour t sub outputstring
  typeset -A wordlist
  while read w
  do
      if (( ${#w} == 4 ))
      then lastfour=$w
      elif (( ${#w} == 5 )) && [[ $w != *\'* ]] && ( [[ ${w:4:1} != "s" ]]\
           || [[ ${w:0:4} != $lastfour ]] )
      then wordlist[${w:0:3}]=${wordlist[${w:0:3}]}$w
      fi
   done < /usr/dict/words
   for w in ${!wordlist[@]}
   do
      t=${wordlist[$w]}
      (( nwords = ${#t} / 5 ))
      if (( nwords > 1 ))
      then
        sub=${t:0:5}
        outputstring=$outputstring"$w $nwords\t$sub\n"
        for (( n = 1; n < $nwords; n++ ))
        do
          sub=${t:$n*5:5}
          outputstring=$outputstring"\t$sub\n"
        done
      fi
   done
#print $outputstring
}

function stemsloop {
  integer i
  for (( i = 0; i < $1; i++ ))
  do
    stems
  done
}

function systemloop {
  integer i
  for (( i = 0; i < $1; i++ ))
  do
    /bin/echo test >/dev/null
  done
}

function fileloop {
  integer i
  for (( i = 0; i < $1; i++ ))
  do
    integer j;
    for (( j = 0; j < 101; j++ ))
    do
      print "LINE -> $j"
    done > /tmp/tmp
    j=0
    while read line
    do
      (( j++ ))
    done < /tmp/tmp
    if (( j != 101 ))
    then print "WARNING: Retrieved only $j lines!\n"
    fi
  done
}

integer NREPEAT=1000000
integer NIFACT1=10000
integer NIFACT2=10000
integer NFACT=1000       #div 10!
integer NSTEM=10
integer NSYSTEM=1000
integer NFILE=2000
float starttime duration totaltime

((starttime = $SECONDS))
repeatloop $NREPEAT
((duration = $SECONDS - $starttime))
print "$NREPEAT repeats in $((duration))"
((totaltime = $totaltime + duration))

((starttime = $SECONDS))
ifact1loop $NIFACT1
((duration = $SECONDS - $starttime))
print "$NIFACT1 iterative factorial(100) in $((duration))"
((totaltime = $totaltime + duration))

((starttime = $SECONDS))
ifact2loop $NIFACT2
((duration = $SECONDS - $starttime))
print "$NIFACT2 iterative factorial(100) with 'if' in $((duration))"
((totaltime = totaltime + duration))

((starttime = $SECONDS))
factloop $NFACT
((duration = $SECONDS - $starttime))
print "$NFACT recursive factorial(100) in $((duration))"
((totaltime = $totaltime + duration))

((starttime = $SECONDS))
stemsloop $NSTEM
((duration = $SECONDS - $starttime))
print "$NSTEM stems generation in $((duration))"
((totaltime = $totaltime + duration))

((starttime = $SECONDS))
systemloop $NSYSTEM
((duration = $SECONDS - $starttime))
print "$NSYSTEM system echo test in $((duration))"
((totaltime = $totaltime + duration))

((starttime = $SECONDS))
fileloop $NFILE
((duration = $SECONDS - $starttime))
print "$NFILE 100-line writes and reads in $((duration))"
((totaltime = $totaltime + duration))

print "total time was $((totaltime))"