I used the Fibonacci sequence to test the speed of recursive calls in different
languages. Take the results with a grain of salt because my computer is not a
controlled environment. I found that Python was slower than I expected, while
JavaScript was faster than I expected. Bash was more than 100,000 times
slower than C because the Bash benchmark did not finish after the 5-hour mark.
My hypothesis is that Bash is very slow because math is done in sub-shells,
requiring bash to spawn a process for every arithmetic operation.
Execution times for calculating the 39th term of the Fibonacci sequence:
Language
Compiler/Interpreter
Flags
Time (sec)
C
gcc 12.3.0
-O3 -Ofast
0.124
C++
g++ 12.3.0
-O3 -Ofast
0.125
Rust
rustc 1.73.0
-C opt-level=3
0.247
Java
javac/java 17.0.7
None
0.460
JavaScript
node 21.2.0
None
0.802
Lua
lua 5.2.4
None
8.192
Python
python3 3.11.6
None
10.828
Perl
perl 5.38.2
None
38.966
Vimscript
nvim 0.10.0
None
346.000
Bash
bash
None
18000.000
Implementations
C
/**
* @file
* @brief Calculate the a Fibonacci sequence number from user input.
*/
#include <stdio.h>
#include <stdlib.h>
/**
* @brief Calculate a Fibonacci sequence number.
*
* @param term The sequence number to produce. Don't use large
* numbers as the time complexity is exponential.
* @return The sequence number.
*/
int fibonacci ( int term ) {
// Base case.
if ( term <= 1 ) {
return term ;
}
// Recursive step.
return fibonacci ( term - 1 ) + fibonacci ( term - 2 );
}
/**
* @brief Calculate a Fibonacci sequence number from user input.
*
* @param argc The argument count.
* @param argv The argument vector.
* @return The error code.
*/
int main ( int argc , char ** argv ) {
if ( argc > 1 ) {
int term = atoi ( argv [ 1 ]);
int result = fibonacci ( term );
printf ( "%d \n " , result );
}
return 0 ;
}
C++
/**
* @file
* @brief Calculate a Fibonacci sequence number from user input.
*/
#include <iostream>
/**
* @brief Calculate a Fibonacci sequence number.
*
* @param term The sequence number to produce. Don't use large
* numbers as the time complexity is exponential.
* @return The sequence number.
*/
int fibonacci ( int term ) {
// Base case.
if ( term <= 1 ) {
return term ;
}
// Recursive step.
return fibonacci ( term - 1 ) + fibonacci ( term - 2 );
}
/**
* @brief Calculate a Fibonacci sequence number from user input.
*
* @param argc The argument count.
* @param argv The argument vector.
* @return The error code.
*/
int main ( int argc , char ** argv ) {
if ( argc > 1 ) {
int term = std :: stoi ( argv [ 1 ]);
int result = fibonacci ( term );
std :: cout << result << std :: endl ;
}
return 0 ;
}
Rust
//! Calculate a Fibonacci sequence number from user input.
use std :: env :: args ;
/// Calculate a Fibonacci sequence number.
///
/// * `term`: The sequence number to produce. Don't use large numbers as the
/// time complexity is exponential.
fn fibonacci ( term : i32 ) -> i32 {
// Base case.
if term <= 1 {
return term ;
}
// Recursive step.
fibonacci ( term - 1 ) + fibonacci ( term - 2 )
}
/// Calculate a Fibonacci sequence number from user input.
fn main () {
let arguments : Vec < String > = args () .collect ();
if let Some ( argument ) = arguments .get ( 1 ) {
let term : i32 = argument .parse () .unwrap_or ( 0 );
let result = fibonacci ( term );
println! ( "{}" , result );
}
}
Java
/**
* Calculate a Fibonacci sequence number from user input.
*/
class Fibonacci {
/**
* Calculate a Fibonacci sequence number.
*
* @param term The sequence number to produce. Don't use large numbers as
* the time complexity is exponential.
*
* @return The sequence number.
*/
public static int fibonacci ( int term ) {
// Base case.
if ( term <= 1 ) {
return term ;
}
// Recursive step.
return fibonacci ( term - 1 ) + fibonacci ( term - 2 );
}
/**
* Calculate a Fibonacci sequence number from user input.
*
* @param args The command-line arguments.
*/
public static void main ( String [] args ) {
if ( args . length > 0 ) {
int term = Integer . parseInt ( args [ 0 ]);
int result = fibonacci ( term );
System . out . println ( result );
}
}
}
JavaScript
#!/usr/bin/env node
/**
* @module Calculate a Fibonacci sequence number from user input.
*/
/**
* Calculate a Fibonacci sequence number.
*
* @param {number} term The sequence number to produce. Don't use large numbers
* as the time complexity is exponential.
* @returns {number} The sequence number.
*/
function fibonacci ( term ) {
// Base case.
if ( term <= 1 ) {
return term ;
}
// Recursive step.
return fibonacci ( term - 1 ) + fibonacci ( term - 2 );
}
if ( process . argv . length > 2 ) {
const term = parseInt ( process . argv [ 2 ]);
const result = fibonacci ( term );
console . log ( result );
}
Lua
#!/usr/bin/env lua
--- @module Calculate a Fibonacci sequence number from user input.
--- Calculate a Fibonacci sequence number.
--- @param term number The sequence number to produce. Don't use large numbers as
--- the time complexity is exponential.
--- @return number
local function fibonacci ( term )
-- Base case.
if term <= 1 then
return term ;
end
-- Recursive step.
return fibonacci ( term - 1 ) + fibonacci ( term - 2 );
end
if # arg >= 1 then
local term = tonumber ( arg [ 1 ]) or 0 ;
local result = fibonacci ( term );
print ( result );
end
Python
#!/usr/bin/python3
"""Calculate a Fibonacci sequence number from user input."""
from sys import argv
def fibonacci ( term : int ) -> int :
"""Calculate a Fibonacci sequence number.
Args:
term (int): The sequence number to produce. Don't use large numbers as
the time complexity is exponential.
Returns:
int: The sequence number.
"""
# Base case.
if term <= 1 :
return term
# Recursive step.
return fibonacci ( term - 1 ) + fibonacci ( term - 2 )
def main ():
"""Calculate a Fibonacci sequence number from user input."""
if len ( argv ) >= 2 :
term = int ( argv [ 1 ])
result = fibonacci ( term )
print ( result )
if __name__ == "__main__" :
main ()
Perl
#!/usr/bin/env perl
use strict ;
use warnings ;
use feature ' say ';
sub fibonacci {
my $term = shift ;
# Base case.
if ( $term <= 1 ) {
return $term ;
}
# Recursive step.
return fibonacci ( $term - 1 ) + fibonacci ( $term - 2 );
}
sub main {
if ( scalar @ARGV >= 1 ) {
my $value = fibonacci ( int ( $ARGV [ 0 ]));
say ( $value );
}
}
unless ( caller ) {
main ();
}
__END__
=head1 DESCRIPTION
Calculate a Fibonacci sequence number from user input.
=cut
=head1 FUNCTIONS
=over
=item fibonacci($term)
Calculate a Fibonacci sequence number.
$term C<int> is the sequence number to produce. Don't use large numbers as the
time complexity is exponential.
Returns C<int>, the sequence number.
=item main
Calculate a Fibonacci sequence number from user input.
=back
=cut
Vimscript
#! /usr/ bin /env - S nvim -- cmd ":source fibonacci.vim"
function ! Fibonacci( n )
if a:n <= 2
return 1
else
return Fibonacci( a:n - 2 ) + Fibonacci( a:n - 1 )
endif
endfunction
echom Fibonacci( 39 )
quit !
Bash
#!/usr/bin/bash
# Calculate a Fibonacci sequence number from user input.
# Exit on errors and undefined variables.
set -eu
################################################################################
# Calculate a Fibonacci sequence number.
# Arguments:
# $1: int The sequence number to produce. Don't use large numbers as
# the time complexity is exponential.
# Outputs:
# int The sequence number.
################################################################################
fibonacci() {
declare -ir term = $1
# Base case.
if (( term <= 1 )) ; then
echo $term
return
fi
# Recursive step.
echo $(( $( fibonacci $(( term - 1 )) ) + $( fibonacci $(( term - 2 )) ) ))
}
fibonacci $1