Home

Awesome

Recursive Fibonacci Benchmark using top languages on Github

Top 10: JavaScript, Python, Java, TypeScript, C#, Php, C++, C, Shell, Ruby reference

Others: Go, Rust, Swift, Crystal, Pony, Ada, Pascal, Fortran, Kotlin, Clojure, Scala, Mono, R, Dart, Julia, D, Nim, Cython, Python3, PyPy, Ruby jit, OCaml, Lisp, Haskell, Erlang, Elixir, Escript, Dart, Scheme, Lua, Perl, Perl6, Bash, Emoji

The code performs a recursive fibonacci to the 47th position with the result of 2,971,215,073.

Fibonacci can be written many different ways. The goal of this project is to compare how each language handles the exact same code.

Here is the Ruby version:

def fib(n)
  return n if n <= 1
  fib(n - 1) + fib(n - 2)
end

puts fib(47)

Here is the Crystal version:

def fib(n)
  return n if n <= 1
  fib(n - 1) + fib(n - 2)
end

puts fib(47_u64)

Too keep a level playing field, only common "release" flags are used in the compilation step. This allows for compiler optimizations like inlining and constant propogation but removes anything considered dangerous i.e. bypassing out of bounds checks.

All tests are run on:

How to run them

You can run the tests using Docker: docker run -it drujensen/fib

By default, it will compile and run all languages 5 times. Totals are calculated by adding the average compile and run times.

To only run a subset of the languages, provide a list of extensions and optionally the count:

docker run -it drujensen/fib ./run.sh s,c,cpp,go,rs,swift 5

To run in the background using screen:

screen
docker run drujensen/fib > results.txt 2>&1
screen -r

NOTE: Please see issues with benchmarks like this. Its original goal was to compare at a marco level how much faster Crystal is to Ruby. Any language faster than Assembly is performing unrolling type optimizations. Modern languages like Go, Swift and Crystal have bounds checking which have safety built-in, but also have a cost associated with runtime performance.

Results

Last benchmark was ran on December 05, 2024

Natively compiled, statically typed

LanguageTotalCompileTimeRunTimeExt
C4.835gcc -O3 -o fib fib.c0.112./fib4.723c
C++4.888g++ -O3 -o fib fib.cpp0.139./fib4.750cpp
Fortran6.334gfortran -O3 -o fib fib.f030.130./fib6.204f03
Ada6.811gnat make -O3 -gnatp -o fib fib.adb0.220./fib6.591adb
Rust8.108rustc -C opt-level=3 fib.rs0.358./fib7.750rs
Odin8.838odin build fib.odin -file -0:speed0.087./fib8.751odin
Mojo8.947mojo build fib.mojo0.241./fib8.706mojo
V9.168v -prod -o fib fib.v4.450./fib4.718v
Assembly9.367gcc -no-pie -O3 -o fib fib.s0.025./fib9.342s
Pascal10.460fpc -O3 -Si ./fib.pas0.041./fib10.419pas
Pony11.106ponyc -s -b fib -p ./fib.pony0.879./fib10.226pony
OCaml16.018ocamlopt -O3 -o fib fib.ml0.187./fib15.831ml
Zig16.181zig build-exe -OReleaseFast ./fib.zig6.882./fib9.299zig
Haskell18.095rm ./fib.o && ghc -O3 -o fib fib.hs0.001./fib18.094hs
D18.193dmd -release -of=fib fib.d0.342./fib17.851d
Swift18.801swiftc -O fib.swift1.411./fib17.390swift
Go18.948go build fib.go1.107./fib17.842go
Crystal20.525crystal build --release fib.cr3.106./fib17.420cr
Lisp25.726sbcl --load fib.lisp0.979./fib24.747lisp
Dart Compiled31.707dart compile exe -o fib ./fib.dart1.558./fib30.149dartc
Cobol4380.728cobc -x -O3 -o fib ./fib.cbl0.133./fib4380.596cbl

VM compiled bytecode, statically typed

LanguageTotalCompileTimeRunTimeExt
C#12.760dotnet build -c Release -o ./bin2.015dotnet ./bin/fib.dll10.744cs
Java13.040javac Fib.java0.733java Fib12.307java
Scala15.836scalac Fib.scala2.682scala Fib13.153scala
Kotlin16.286kotlinc Fib.kt4.074java FibKt12.212kt
Erlang28.378erlc +native +'{hipe,[o3]}' fib.erl0.402erl -noinput -noshell -s fib27.976erl
Groovy70.123groovyc Fib.groovy1.519groovy Fib68.604groovy

VM compiled before execution, mixed/dynamically typed

LanguageTimeRunExt
Clojure17.815clojure -M fib.cljccljc
Julia18.000julia -O3 fib.jljl
Bun21.312bun fib.jsbun
Dart29.984dart fib.dartdart
Node34.736node fib.jsjs
Elixir35.243ERL_COMPILER_OPTIONS='[native,{hipe, [o3]}]' elixir Fib.exsexs
Lua Jit37.837luajit fib.lualuajit
Python (PyPy)54.078pypy fib.pypypy
Ruby (jit)81.454ruby --jit fib.rbrbjit

Interpreted, dynamically typed

LanguageTimeRunExt
Escript28.380escript fib.eses
Scheme102.887guile fib.scmscm
Php157.312php fib.phpphp
Lua203.702lua fib.lualua
Ruby393.625ruby fib.rbrb
Python423.427python fib.pypy
Janet479.663janet ./fib.janetjanet
Perl1490.416perl fib.plpl
Raku1672.015rakudo fib.rakuraku
Tcl2230.883tclsh fib.tcltcl
R2575.249R -f fib.rr

Versions

All compilers are installed using apt or asdf on Ubuntu 24.04 docker image:

LanguageVersion
ada13.2.0
assembly13.2.0
bash5.2.21
bun1.1.38
crystal1.14.0
clojure1.12.0.1488
dart3.5.4
dmd2.109.1
dotnet9.0.101
elixir1.17.3
elm0.19.1
erlang27.1.2
fortran13.2.0
g++13.2.0
gcc13.2.0
gnucobol3.2.0
golang1.23.2
groovy4.0.24
guile3.0.10
haskell9.8.3
janet1.36.0
javaopenjdk-23
julia1.11.1
K3.6
kotlin2.1.0
ldc1.39.0
lua5.4.7
luajit2.1.1
mojo24.5.0
nim2.2.0
nodejs23.3.0
ocaml5.2.1
odindev-2024-11
pascal3.2.2
perl5.40.0
php8.4.1
pony0.58.7
powershell-core7.4.6
python3.12.0
pypy7.3.17
r4.4.2
rakudo2024.10
ruby3.3.6
rust1.83.0
sbcl2.4.11
scala3.3.4
swift6.0.2
tcl9.0.0
v0.4.8
zig0.13.0