'How to find the amount of time taken during Iterative loop?

Trying to subtract two times down to the nanosecond in shell.

declare start

function handler() {
count=$1

if [ "$1" -le 0 ]; then
  echo "Not a valid entry"
  exit
  fi

  read -p "Enter in R or N: " VAR1
  VAR2="R"
  VAR3="r"
  VAR4="N"
  VAR5="n"

  date +"%A %B %d, %Y %T.%N"
  start=$(date +"%T.%N")
  if [ "$VAR1" = "$VAR2" ]; then
    recFib "$1" "$start"
  elif [ "$VAR1" = "$VAR3" ]; then
    recFib "$1" "$start"
  elif [ "$VAR1" = "$VAR4" ]; then
    itFib "$1" "$start"
  elif [ "$VAR1" = "$VAR5" ]; then
    itFib "$1" "$start"
  else
    echo "Not a valid input"
  fi

}

function recFib() {

  if [ $1 -le 0 ]; then
    echo 0
  elif [ $1 -eq 1 ]; then
    echo 1
  else
    stop=$(date +"%T.%N")
    echo $((date $stop-$start))
    echo $(($(recFib $(($1 - 2))) + $(recFib $(($1 - 1)))))
  fi

}

I have tried this a number of different ways however I am not sure how to perform the subtraction on the two times. Since it is recursive I am trying to grab the time after each generation.



Solution 1:[1]

You must use something that supports floating point math. You can use bc or you can use awk. For example, let's say you have a start and end time of:

01:39:47.109964128
01:43:07.280513101

To get the time difference, you can simply pipe the two times to awk on separate lines. Below with the start time first and stop time second, e.g.:

$ echo -e "01:39:47.109964128\n01:43:07.280513101" |
awk -F: '
  FNR==1 {h1=$1; m1=$2; s1=$3; next} 
  {h2=$1; m2=$2; s2=$3; exit} 
  END { 
    if (s2 < s1) {s2 += 60; m2 -= 1} 
    printf "%02d:%02d:%012.9f\n", h2-h1, m2-m1, s2-s1 }
'
00:03:20.170548973

Where h1, m1, s1 are hour-start, minute-start, seconds-start, etc....


For a solution with date, you have to convert both start time and stop time to seconds since epoch, e.g. '+%s.%N' and then pipe the subtraction of seconds.nanoseconds to bc and then you need to convert back to H:M:S.N format.

Solution 2:[2]

Use

start=$(date +%s.%N)
stop=$(date +%s.%N)

Using only %s and %N is timezone independent (like -u). So hazards on summer time switch are suppressed.

To get the difference, use:

duration=$( bc <<<"$stop-$start" )

Solution 3:[3]

Why not move

stop=$(date +"%T.%N")
echo $((date $stop-$start))

to the end of function handler() body.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 David C. Rankin
Solution 2
Solution 3 Victor Lee