0

I have the following bash code (A.cpp, B.cpp and C.txt are filename in the current directory):

#!/bin/bash
g++ A.cpp -o A
g++ B.cpp -o B
Inputfiles=(X Y Z U V)

for j in "${Inputfiles[@]}"
do
   echo $j.txt:
i=1
    while [ $i -le 5 ]
    do
        ./A $j.txt
        ./B C.txt
        echo ""
        i=`expr $i + 1`
    done
    echo ""
done
 
rm -f A B

One execution of ./A and ./B is one execution of my program. I run my program 5 times for each input file in the array 'Inputfiles'. I want the average execution time of my program over each input-file. How can I do so?

(Earlier, I tried to add time and clock functions within the A.cpp and B.cpp files, but I am not able to add the execution times of both files to get the execution time of a program.)

Anon
  • 381
  • 1
  • 2
  • 13

1 Answers1

1

If I understand correctly what average you would like to calculate, I think the code below will serve your purpose.

Some explanations on the additions to your script:

  • Lines 6 - 14 declare a function that expects three arguments and updates the accumulated total time, in seconds
  • Line 26 initializes variable total_time.
  • Lines 31, 38, execute programs A and B respectively. Using bash time to collect the execution time. >/dev/null "discards" A's and B's outputs. 2>&1 redirects stderr to stdout so that grep can get time's outputs (a nice explanation can be found here). grep real keeps only the real output from time, you could refer to this post for an explanation of time's output and choose the specific time of your interest. awk {print $2} keeps only the numeric part of grep's output.
  • Lines 32, 39 store the minutes part to the corresponding variable
  • Lines 33-34, 40-41 trim the seconds part of real_time variable
  • Lines 35, 42 accumulate the total time by calling function accumulate_time
  • Line 46 calculates the average time by dividing with 5
  • Converted the while loop to a nested for loop and introduced the iterations variable, not necessarily part of the initial question but helps re-usability of the number of iterations
  1 #!/bin/bash
  2 
  3 # Function that receives three arguments (total time,
  4 # minutes and seconds) and returns the accumulated time in
  5 # seconds
  6 function accumulate_time() {
  7     total_time=$1
  8     minutes=$2
  9     seconds=$3
 10 
 11     accumulated_time_secs=$(echo "$minutes * 60 + $seconds + $total_time" | bc )
 12     echo "$accumulated_time_secs"
 13 
 14 }
 15 
 16 g++ A.cpp -o A
 17 g++ B.cpp -o B
 18 Inputfiles=(X Y Z U V)
 19 
 20 iterations=5
 21 
 22 for j in "${Inputfiles[@]}"
 23 do
 24     echo $j.txt:
 25     # Initialize total_time
 26     total_time=0.0
 27 
 28     for i in $(seq 1 $iterations)
 29     do
 30         # Execute A and capture its real time
 31         real_time=`{ time ./A $j.txt >/dev/null; } 2>&1 | grep real | awk '{print $2}'`
 32         minutes=${real_time%m*}
 33         seconds=${real_time#*m}
 34         seconds=${seconds%s*}
 35         total_time=$(accumulate_time "$total_time" "$minutes" "$seconds")
 36 
 37         # Execute B and capture its real time
 38         real_time=`{ time ./B C.txt >/dev/null; } 2>&1 | grep real | awk '{print $2}'`
 39         minutes=${real_time%m*}
 40         seconds=${real_time#*m}
 41         seconds=${seconds%s*}
 42         total_time=$(accumulate_time "$total_time" "$minutes" "$seconds")
 43         echo ""
 44     done
 45 
 46     average_time=$(echo "scale=3; $total_time / $iterations" | bc)
 47     echo "Average time for input file $j is: $average_time"
 48 done
 49 
 50 rm -f A B
Zois Tasoulas
  • 1,242
  • 1
  • 11
  • 23