Timing performance of functions in shell scripts

December 30, 2021 #shell #linux #benchmarking

I recently started looking at some shell scripts that run fine on big fast powerful systems (i.e. x86 laptops/desktops), but quite slowly on small slow devices. Using time to run the script (or, the amazing hyperfine) works OK if you're timing the entire script execution, but what do you do if you want to time individual functions within the script?

Well without getting too fancy, I came up with the following, which is capable of timing far below 1 second:

$!/bin/sh

foo() {
    # do real work
    sleep 4
}

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

foo

end=$(date +%s.%N)
echo "foo: $( echo "$end - $start" | bc -l ) seconds..."

It's not the most accurate thing in the world, and you'll pay some penalty for running date in a sub shell, twice, but it works well for blaming slowdowns in a shell script.

$ ./run.sh
foo: 4.037054796 seconds...