Or why you better not use recursion is Bash
First, the loop version:
function fib() { declare -l cur=0 next=1 final=$(($1-1)) tcur for ((i=0; i<final; i++)); do tcur=$cur cur=$next next=$((tcur+next)) done rval=$cur }
And now the recursive version. I've added caching of previously calculated values to help with performance:
unset fib_cache; declare -ia fib_cache function fib() { declare -li n=$1 n_1 n_2 l l=${#fib_cache[*]} if ((n<=l)); then rval=${fib_cache[$n]} return fi if ((n<3)); then rval=$((n-1)) fib_cache[$n]=$rval return fi fib $((n-2)) n_2=$rval fib $((n-1)) n_1=$rval rval=$((n_2 + n_1)) fib_cache[$n]=$rval return }
Performance
Lets test how fast Bash can crunk Fibonacci on my laptop. Here is the test script:for i in $(seq 1000); do unset fib_cache; declare -ia fib_cache fib 93 doneI've used
fib 93
- its a max Fibonacci sequence number you can store in Bash arithmetic variable before getting overflow.
I've run it 10 times and measured average time:
- Loop version: Runs 1.19 seconds on average. I.e. it takes 1.19 seconds to calculate
fib 93
thousand times. How fast is that? Well, similar C code, compiled with-O3
runs this task in 0.0001 seconds. About 10,000 faster - Recursion version: Runs 10.41 seconds on average. Times 10 slower. And this is with cache. Without cache it did not complete in 15 minutes and I gave up
No comments:
Post a Comment