Skip to content

AIRacks/benchmarks

 
 

Repository files navigation

Table of Content

Overview

The benchmarks follow the criteria:

  • They are written as the average software developer would write them, i.e.

    • The algorithms are implemented as cited in public sources;
    • The libraries are used as described in the tutorials, documentation and examples;
    • The used data structures are idiomatic.
  • The used algorithms are similar between the languages (as the reference implementations), variants are acceptable if the reference implementation exists.

  • All final binaries are releases (optimized for performance if possible) as debug performance may vary too much depending on the compiler.

My other benchmarks: jit-benchmarks, crystal-benchmarks-game

Measurements

The measured values are:

  • time spent for the benchmark execution (loading required data and code self-testing are not measured);
  • memory consumption of the benchmark process, reported as base + increase, where base is the RSS before the benchmark and increase is the peak increase of the RSS during the benchmark;
  • energy consumption of the CPU (PP0 package) during the benchmark.

All values are presented as: median±median absolute deviation.

UPDATE: 2021-05-11

Test Cases

Brainfuck

Testing brainfuck implementations using two code samples (bench.b and mandel.b). Supports two mode:

  • Verbose (default). Prints the output immediately.
  • Quiet (if QUIET environment variable is set). Accumulates the output using Fletcher-16 checksum, and prints it out after the benchmark.

Brainfuck

bench.b

Language Time, s Memory, MiB Energy, J
C++/g++ 0.887±0.040 1.49±00.01 + 0.00±00.00 18.53±01.68
Racket (Syntax Objects) 1.435±0.058 106.70±00.51 + 0.00±00.00 30.78±03.00
D/ldc2 1.719±0.021 3.02±00.03 + 0.00±00.00 38.72±00.76
Kotlin 1.722±0.024 39.23±00.11 + 1.63±00.21 38.90±00.37
Rust 1.785±0.053 2.06±00.10 + 0.00±00.00 37.35±03.03
C/gcc 1.893±0.050 0.53±00.03 + 0.00±00.00 37.71±03.11
D/gdc 2.002±0.046 6.41±00.04 + 0.00±00.00 36.57±02.44
Go/gccgo 2.047±0.026 21.44±00.58 + 0.00±00.00 43.83±02.01
Go 2.130±0.014 3.49±00.01 + 0.00±00.00 48.08±01.27
Java 2.132±0.075 38.29±00.22 + 0.86±00.28 46.92±01.37
Nim/clang 2.248±0.071 2.34±00.04 + 0.00±00.00 46.76±03.92
Vala/gcc 2.265±0.062 3.76±00.04 + 0.00±00.00 46.50±02.06
C/clang 2.272±0.032 0.50±00.00 + 0.00±00.00 42.58±01.16
OCaml 2.298±0.053 2.61±00.02 + 2.50±00.06 41.39±01.07
Racket 2.333±0.041 115.66±00.14 + 2.32±00.13 46.43±05.60
Vala/clang 2.354±0.034 3.70±00.03 + 0.00±00.00 54.43±00.72
Nim/gcc 2.362±0.035 1.85±00.04 + 0.00±00.00 43.36±01.52
F#/.NET Core 2.393±0.032 36.88±00.12 + 0.29±00.00 41.65±00.69
C#/.NET Core 2.401±0.044 34.35±00.02 + 0.07±00.00 44.16±02.20
V/gcc 2.427±0.082 0.53±00.03 + 0.00±00.00 53.52±02.12
Crystal 2.528±0.077 3.32±00.02 + 0.00±00.00 44.50±01.79
MLton 2.744±0.104 1.44±00.01 + 0.25±00.00 57.60±05.55
Chez Scheme 3.041±0.033 24.85±00.04 + 4.23±00.02 54.88±01.72
Julia 3.161±0.136 198.80±00.11 + 0.78±00.05 62.44±04.55
Scala 3.554±0.028 72.40±00.34 + 41.53±01.76 70.90±01.48
D/dmd 3.703±0.086 3.61±00.06 + 0.00±00.00 67.36±02.74
Node.js 4.109±0.159 30.70±00.06 + 3.57±00.00 79.59±06.43
C#/Mono 4.358±0.119 20.14±00.05 + 0.00±00.00 77.73±01.73
Haskell (MArray) 4.415±0.084 3.68±00.08 + 1.17±00.00 100.95±03.60
V/clang 4.787±0.124 0.86±00.00 + 0.00±00.00 84.16±01.42
Lua/luajit 6.388±0.145 2.92±00.04 + 0.00±00.00 133.80±03.92
Ruby/truffleruby (--jvm) 7.893±0.199 589.00±09.65 + 662.55±30.78 279.51±12.92
Ruby/truffleruby 8.783±0.230 415.87±00.79 + 530.82±09.17 183.15±04.44
Python/pypy 14.000±0.092 65.46±00.15 + 45.49±00.04 352.08±04.58
Haskell 16.657±0.379 3.95±00.18 + 0.88±00.06 319.16±16.43
Lua 56.144±1.050 2.98±00.02 + 0.00±00.00 1235.91±12.80
Ruby (--jit) 59.070±1.495 14.10±00.04 + 0.20±00.03 1270.83±51.58
Ruby 95.925±1.875 14.04±00.03 + 0.00±00.00 1730.34±29.57
Ruby/jruby 108.937±3.967 193.93±06.81 + 125.95±14.62 2207.07±64.21
Elixir 118.452±3.773 56.35±00.67 + 0.00±00.00 2452.64±141.77
Python 225.315±5.268 10.44±00.01 + 0.00±00.00 4895.03±190.72
Tcl (FP) 278.444±4.141 4.30±00.06 + 0.00±00.00 5439.77±216.82
Perl 362.032±4.739 6.55±00.07 + 0.00±00.00 7367.39±522.22
Tcl (OOP) 542.918±12.654 4.31±00.05 + 0.00±00.00 11537.98±493.52

mandel.b

Mandel in Brainfuck

Language Time, s Memory, MiB Energy, J
C/gcc 12.811±0.524 0.55±00.01 + 1.11±00.03 250.85±22.32
D/ldc2 13.156±0.445 3.07±00.07 + 0.77±00.00 263.50±24.22
C++/g++ 13.376±0.399 3.28±00.06 + 0.47±00.01 268.43±14.79
Rust 13.398±0.182 2.19±00.04 + 0.25±00.00 247.32±04.90
D/gdc 14.413±0.763 6.74±00.04 + 0.52±00.00 251.18±05.29
V/gcc 14.937±0.295 1.64±00.16 + 0.77±00.00 338.31±06.91
Go 16.134±0.570 3.46±00.06 + 1.28±00.00 348.96±19.77
Racket (Syntax Objects) 16.351±0.443 107.54±00.70 + 71.80±00.77 371.05±16.84
Kotlin 17.211±0.691 39.24±00.11 + 1.97±00.11 336.46±31.35
C/clang 18.082±0.838 0.50±00.00 + 1.13±00.02 387.24±37.25
C#/.NET Core 19.026±0.221 34.34±00.06 + 1.00±00.00 340.41±16.20
Vala/gcc 19.971±0.342 3.59±00.04 + 2.07±00.02 375.26±10.38
Vala/clang 20.499±0.344 3.57±00.04 + 2.07±00.04 485.68±16.04
Java 21.451±1.883 38.19±00.28 + 1.43±00.28 450.02±68.42
Nim/gcc 22.354±0.356 1.77±00.02 + 0.51±00.00 503.29±12.39
Go/gccgo 22.808±0.725 21.28±00.11 + 1.28±00.00 451.37±38.88
Nim/clang 22.928±0.263 2.31±00.05 + 0.54±00.03 421.51±07.00
Scala 23.253±0.610 73.66±00.63 + 25.55±01.13 499.19±33.30
V/clang 23.440±0.355 2.10±00.09 + 0.77±00.00 527.86±19.44
Crystal 24.435±0.992 3.38±00.02 + 0.38±00.04 515.33±46.04
F#/.NET Core 34.565±0.365 36.82±00.07 + 2.03±00.00 628.43±12.89
OCaml 38.112±0.568 3.91±00.02 + 6.82±00.13 709.65±06.96
Racket 38.938±2.272 115.69±00.18 + 1.80±00.39 828.00±47.60
Chez Scheme 39.375±0.585 25.49±00.03 + 3.72±00.09 922.02±20.81
Node.js 41.226±0.585 30.64±00.08 + 6.71±00.00 732.87±13.37
D/dmd 45.699±1.554 3.64±00.03 + 0.77±00.00 921.76±67.84
C#/Mono 46.799±0.359 20.19±00.06 + 0.88±00.00 839.48±10.27
MLton 50.137±0.535 1.47±00.07 + 4.11±00.00 1158.49±27.73
Python/pypy 61.742±1.887 65.24±00.03 + 46.46±00.04 1326.92±93.95
Haskell (MArray) 62.608±1.184 3.90±00.12 + 2.43±00.00 1227.45±111.27
Julia 78.557±0.670 199.37±00.28 + 0.96±00.12 1441.81±25.06
Ruby/truffleruby (--jvm) 131.607±0.986 575.77±07.17 + 670.21±93.59 2784.49±53.43
Ruby/truffleruby 145.901±2.851 416.55±00.22 + 616.44±13.62 3272.93±77.01
Haskell 209.454±2.302 4.12±00.07 + 25.91±00.00 4779.38±134.86
Lua/luajit 234.265±0.831 2.95±00.05 + 0.86±00.00 5391.35±54.50

Base64

Testing base64 encoding/decoding of the large blob into the newly allocated buffers.

Base64

Language Time, s Memory, MiB Energy, J
C/gcc (aklomp) 0.158±0.003 1.92±00.05 + 0.00±00.00 3.62±00.19
Rust 1.099±0.012 2.50±00.08 + 0.00±00.00 25.03±00.53
C/gcc 1.204±0.018 1.88±00.00 + 0.00±00.00 25.03±00.92
Nim/gcc 1.315±0.051 2.17±00.03 + 4.44±00.00 26.36±02.48
V/gcc 1.536±0.025 1.53±00.07 + 0.57±00.15 32.53±00.75
Crystal 1.607±0.005 3.78±00.02 + 1.73±00.05 38.11±00.24
Nim/clang 1.737±0.034 2.74±00.02 + 4.38±00.00 30.87±01.37
D/gdc 1.986±0.055 7.10±00.07 + 3.46±00.00 43.83±01.58
Ruby 2.000±0.015 14.45±00.06 + 55.93±00.77 45.58±00.47
D/ldc2 2.016±0.030 3.41±00.03 + 3.67±00.00 34.76±00.15
Ruby (--jit) 2.142±0.038 14.48±00.04 + 55.32±02.00 40.99±01.63
Vala/clang 2.166±0.102 2.48±02.48 + 0.21±00.21 42.94±04.07
Java 2.205±0.032 38.88±00.12 + 284.38±12.77 49.29±02.07
Vala/gcc 2.222±0.066 2.50±02.50 + 0.23±00.23 40.61±03.76
V/clang 2.366±0.022 2.01±00.09 + 0.57±00.14 40.70±01.40
Kotlin 2.374±0.055 40.35±00.09 + 305.36±35.98 47.30±01.56
Scala 2.456±0.022 73.41±00.80 + 53.48±02.23 48.65±02.17
C++/g++ (libcrypto) 2.589±0.115 5.46±00.02 + 0.07±00.00 50.14±05.06
Go 2.592±0.010 4.59±00.04 + 5.38±00.19 49.56±00.40
Node.js 2.797±0.060 31.26±00.06 + 36.71±00.05 59.13±02.46
PHP 2.976±0.073 15.94±00.10 + 0.00±00.00 64.81±02.71
Perl (MIME::Base64) 3.104±0.042 14.17±00.04 + 0.05±00.03 53.43±01.27
Go/gccgo 3.527±0.007 22.10±00.04 + 7.29±00.24 76.38±00.50
Python 3.842±0.072 10.13±00.04 + 0.18±00.00 86.80±02.81
D/dmd 3.899±0.016 3.74±00.06 + 3.67±00.06 65.86±02.37
Tcl 4.931±0.052 4.82±00.07 + 0.16±00.03 85.15±01.71
Python/pypy 5.388±0.153 65.31±00.10 + 45.70±00.04 113.66±07.17
F#/.NET Core 5.447±0.057 37.06±00.05 + 33.01±05.24 101.12±01.56
C#/.NET Core 5.762±0.016 34.55±00.06 + 36.93±05.76 109.67±00.38
Julia 5.900±0.107 218.04±00.18 + 63.00±00.12 112.60±03.40
Ruby/truffleruby (--jvm) 6.878±0.224 572.64±10.58 + 326.01±39.19 140.38±10.99
C#/Mono 7.497±0.315 20.73±00.04 + 18.41±00.02 152.30±12.76
Ruby/jruby 10.952±0.463 190.82±05.19 + 137.54±19.63 229.20±12.38
Perl (MIME::Base64::Perl) 17.158±0.337 15.48±00.02 + 0.20±00.04 308.64±18.30
Ruby/truffleruby 22.370±0.368 406.16±01.08 + 304.93±01.49 471.43±17.59

Json

Testing parsing and simple calculating of values from a big JSON file.

Few notes:

Json

Language Time, s Memory, MiB Energy, J
C++/g++ (DAW JSON Link NoCheck) 0.091±0.002 113.03±00.04 + 0.00±00.00 2.24±00.21
C++/g++ (simdjson On-Demand) 0.107±0.008 113.22±00.06 + 59.81±00.00 2.60±00.51
C++/g++ (DAW JSON Link) 0.130±0.003 113.04±00.06 + 0.00±00.00 3.32±00.13
Rust (Serde Custom) 0.148±0.006 111.84±00.06 + 0.00±00.00 3.23±00.24
Rust (Serde Typed) 0.160±0.004 111.92±00.07 + 11.54±00.13 3.96±00.31
C++/g++ (gason) 0.173±0.003 113.03±00.08 + 96.77±00.03 4.06±00.26
C++/g++ (simdjson DOM) 0.184±0.002 113.21±00.06 + 176.60±00.00 4.46±00.21
C++/g++ (RapidJSON) 0.234±0.003 113.06±00.06 + 128.71±00.06 5.61±00.15
D/ldc2 (Mir Amazon's Ion DOM) 0.239±0.003 112.74±00.04 + 16.27±00.01 5.47±00.28
D/ldc2 (Mir Asdf DOM) 0.261±0.004 112.59±00.02 + 61.34±00.00 6.06±00.19
C++/g++ (RapidJSON Precise) 0.314±0.007 113.09±00.04 + 128.71±00.06 7.22±00.35
C++/g++ (Boost.JSON) 0.562±0.015 113.15±00.01 + 435.70±00.00 12.84±00.15
C++/g++ (RapidJSON SAX) 0.602±0.016 112.83±00.01 + 0.00±00.00 12.69±00.56
C++/g++ (RapidJSON SAX Precise) 0.700±0.024 112.85±00.02 + 0.00±00.00 14.49±00.47
Go (jsoniter) 0.727±0.008 231.44±00.12 + 1.96±00.46 16.74±00.33
Crystal (Pull) 0.794±0.010 113.73±00.04 + 18.24±00.02 17.82±01.17
Crystal (Schema) 0.807±0.021 113.76±00.02 + 47.30±00.08 17.04±00.92
Java 0.808±0.015 264.22±00.12 + 282.49±20.79 22.96±01.85
Rust (Serde Untyped) 0.894±0.022 111.84±00.09 + 839.98±00.00 18.87±00.60
Scala 0.907±0.014 314.85±01.13 + 118.21±01.29 23.79±00.54
V/clang 0.933±0.022 111.53±00.05 + 484.37±00.00 20.55±01.05
Python/pypy 0.938±0.011 285.41±00.06 + 121.42±00.00 20.32±00.84
Node.js 0.972±0.034 250.74±00.08 + 79.32±00.49 23.35±00.97
V/gcc 1.026±0.026 111.04±00.02 + 484.36±00.06 22.22±00.83
Julia (JSON3) 1.028±0.023 384.45±02.15 + 360.66±00.06 22.65±00.58
Perl (Cpanel::JSON::XS) 1.113±0.033 124.71±00.04 + 402.72±00.00 24.41±00.54
Crystal 1.125±0.023 113.69±00.05 + 396.44±00.04 25.19±01.06
C#/.NET Core (System.Text.Json) 1.147±0.025 479.06±00.07 + 139.03±00.03 23.70±00.72
Go 1.176±0.027 117.28±00.09 + 83.24±00.13 26.45±01.29
Nim/clang (Packedjson) 1.184±0.019 112.49±00.14 + 294.04±00.13 27.24±00.78
PHP 1.345±0.044 125.09±00.11 + 682.01±00.00 29.04±01.66
Nim/gcc (Packedjson) 1.436±0.016 111.89±00.06 + 294.16±00.00 31.25±01.11
Go/gccgo 1.575±0.047 135.92±00.11 + 96.10±00.14 33.84±02.52
C++/g++ (json-c) 1.695±0.044 113.25±00.04 + 1215.90±00.00 36.72±01.15
Clojure 1.700±0.005 467.34±08.42 + 592.99±38.56 48.41±02.76
C#/.NET Core 1.759±0.026 487.88±00.19 + 294.07±00.00 41.30±01.21
Nim/clang 1.781±0.038 112.57±00.07 + 924.83±00.06 38.88±00.81
C++/g++ (Nlohmann) 1.910±0.037 113.18±00.04 + 447.88±00.00 39.83±01.09
Nim/gcc 1.931±0.014 111.90±00.16 + 923.48±00.06 42.11±00.68
Python 1.990±0.034 120.11±00.03 + 377.21±00.00 42.55±01.15
CPython (UltraJSON) 2.064±0.009 121.82±00.02 + 547.12±01.15 42.96±00.63
Haskell 2.382±0.025 4.63±00.04 + 4.57±00.05 54.14±02.72
D/gdc 2.484±0.058 116.69±00.01 + 600.52±00.00 52.78±01.35
C#/Mono 2.494±0.046 476.32±00.12 + 0.20±00.01 52.99±00.25
Ruby (YAJL) 2.611±0.061 123.93±00.06 + 283.33±00.01 55.46±01.13
Ruby 2.655±0.053 123.94±00.06 + 410.70±00.01 57.79±00.69
D/ldc2 2.714±0.045 112.99±00.06 + 680.10±00.03 60.21±00.73
Ruby (--jit) 2.748±0.051 123.99±00.06 + 410.83±00.02 59.68±02.08
F#/.NET Core (System.Text.Json) 2.782±0.083 485.25±00.02 + 458.10±01.50 59.53±00.97
Rust (jq) 3.851±0.043 113.80±00.03 + 778.63±00.52 83.66±02.95
Ruby/jruby 4.053±0.093 475.28±09.71 + 1453.79±63.41 120.61±06.17
C++/g++ (Boost.PropertyTree) 4.762±0.020 112.97±00.01 + 1440.06±00.00 109.12±01.30
D/dmd 5.441±0.048 113.53±00.04 + 680.07±00.01 116.61±02.35
Vala/clang 5.744±0.190 0.00±00.00 + 0.00±00.00 119.93±07.93
Vala/gcc 5.753±0.114 0.00±00.00 + 0.00±00.00 115.87±04.04
Perl (JSON::Tiny) 12.644±0.097 125.30±00.05 + 528.60±00.03 296.84±02.64
Ruby/truffleruby (--jvm) 17.785±0.455 730.51±19.39 + 1732.07±55.80 507.44±26.29
Ruby/truffleruby 42.449±1.081 739.47±02.07 + 2276.93±53.78 929.08±21.76

Matmul

Testing allocating and multiplying matrices.

Matmul

Language Time, s Memory, MiB Energy, J
D/ldc2 (lubeck) 0.085±0.002 6.76±00.04 + 55.76±00.22 4.61±00.04
Python (NumPy) 0.108±0.004 27.63±00.07 + 57.60±00.05 5.84±00.20
Nim/gcc (Arraymancer) 0.173±0.018 5.78±00.19 + 57.17±00.24 8.71±00.71
Nim/clang (Arraymancer) 0.198±0.031 6.51±00.15 + 57.29±00.14 9.23±01.58
C++/g++ (Eigen) 0.206±0.003 3.63±00.12 + 85.24±00.00 4.39±00.27
Julia (threads: 8) 0.207±0.003 250.73±00.19 + 53.19±00.18 11.05±00.52
Java (ND4J) 0.240±0.020 143.60±01.12 + 87.67±00.19 10.00±00.44
Julia (threads: 1) 0.576±0.029 250.56±00.21 + 53.47±00.03 12.40±01.44
Julia (no BLAS) 1.232±0.015 215.90±00.38 + 51.62±00.00 34.45±01.82
D/ldc2 2.018±0.012 3.62±00.10 + 70.11±00.00 45.11±00.98
D/dmd 2.176±0.027 3.60±00.04 + 70.12±00.01 47.58±02.18
D/gdc 2.187±0.061 6.70±00.05 + 70.69±00.01 47.76±03.85
Java 3.242±0.017 38.79±00.11 + 81.31±00.26 75.38±01.65
Vala/gcc 3.307±0.028 0.00±00.00 + 0.00±00.00 76.50±01.42
C/gcc 3.312±0.051 2.02±00.02 + 68.06±00.00 75.63±01.60
Scala 3.358±0.037 74.55±00.14 + 80.89±02.57 77.15±01.21
Nim/gcc 3.397±0.032 2.54±00.05 + 65.48±00.00 81.01±02.16
Vala/clang 3.444±0.037 0.00±00.00 + 0.00±00.00 73.45±00.73
Rust 3.470±0.027 2.66±00.10 + 68.32±00.00 72.74±02.13
Nim/clang 3.521±0.064 3.07±00.04 + 66.00±00.00 73.80±02.69
Swift 3.592±0.062 144.95±00.04 + 60.57±00.11 77.32±05.12
Go/gccgo 3.625±0.107 21.46±00.17 + 72.64±00.21 73.94±01.38
Go 3.703±0.069 3.81±00.06 + 73.15±00.16 76.23±03.19
Crystal 3.846±0.079 4.35±00.22 + 59.43±00.20 74.47±04.61
Kotlin 4.004±0.049 38.59±00.08 + 81.24±00.28 71.75±02.87
V/gcc 4.441±0.091 2.03±00.01 + 68.84±00.00 101.20±04.11
Node.js 4.880±0.066 34.66±00.06 + 71.10±00.51 89.68±01.26
Python/pypy 6.520±0.261 65.66±00.04 + 69.17±00.01 125.66±14.87
C#/.NET Core 7.198±0.360 33.93±00.07 + 69.10±00.00 158.94±15.34
C#/Mono 11.556±0.242 20.18±00.06 + 69.02±00.01 203.32±11.33
V/clang 14.623±0.382 2.45±00.01 + 68.84±00.00 252.93±19.56
Ruby/truffleruby 47.034±0.518 574.51±01.27 + 685.30±03.53 1115.82±23.55
Ruby/truffleruby (--jvm) 68.261±0.796 661.51±19.86 + 687.85±116.10 1692.73±54.29
Ruby 222.057±4.896 15.23±00.05 + 68.61±00.03 4820.25±86.57
Ruby (--jit) 228.150±7.978 15.22±00.03 + 68.94±00.00 4876.27±300.59
Python 242.022±9.447 10.51±00.05 + 68.58±00.00 5144.17±38.18
Tcl 349.675±11.664 7.21±00.04 + 400.41±00.03 7854.20±662.18
Perl 399.854±8.563 8.97±00.06 + 599.61±00.06 9746.56±110.95
Ruby/jruby 517.823±21.836 275.39±08.95 + 992.21±54.98 11588.29±403.88

Primes

Testing:

  • generating primes using the optimized sieve of Atkin;
  • prefix search for their decimal numbers using Trie data structure.

Primes

Language Time, s Memory, MiB Energy, J
Java 0.175±0.005 37.15±00.16 + 105.70±01.87 5.75±00.10
Rust 0.213±0.001 2.32±00.12 + 68.10±00.00 4.32±00.04
Node.js 0.281±0.002 30.80±00.04 + 171.14±00.09 7.99±00.21
C++/g++ 0.284±0.005 3.22±00.03 + 125.88±00.00 6.04±00.22
Scala 0.444±0.005 72.45±00.34 + 159.94±01.62 17.05±00.79
Python/pypy 0.736±0.015 64.72±00.02 + 207.20±00.28 16.24±00.90
Python 3.765±0.142 10.29±00.05 + 198.18±00.77 78.34±03.71

Tests Execution

Environment

CPU: Intel(R) Core(TM) i7-10710U

Base Docker image: Debian GNU/Linux bullseye/sid

Language Version
.NET Core 5.0.202
C#/.NET Core 3.9.0-6.21160.10 (59eedc33)
C#/Mono 6.12.0.122
C/clang 11.0.1
C/gcc 10.2.1
Chez Scheme 9.5.4
Clojure "1.10.3"
Crystal 1.0.0
D/dmd v2.096.1
D/gdc 10.2.1
D/ldc2 1.26.0
Elixir 1.10.3
F#/.NET Core 11.3.2.0 for F# 5.0
Go go1.16.4
Go/gccgo 10.2.1
Haskell 8.10.4
Java 16
Julia v"1.6.1"
Kotlin 1.5.0
Lua Lua 5.4
Lua/luajit LuaJIT 2.1.0-beta3
MLton 20210117
Nim 1.4.6
Node.js v16.1.0
OCaml 4.11.1
PHP 7.4.15
Perl v5.32.1
Python 3.9.2
Python/pypy 7.3.4-final0 for Python 3.7.10
Racket "8.1"
Ruby 3.0.1p64
Ruby/jruby 9.2.17.0
Ruby/truffleruby 21.1.0
Rust 1.52.0
Scala 2.13.5
Swift swift-5.4-RELEASE
Tcl 8.6
V 0.2.2
Vala 0.48.15

Using Docker

Build the image:

$ docker build docker/ -t benchmarks

Run the image:

$ docker run -it --rm -v $(pwd):/src benchmarks <cmd>

where is:

  • versions (print installed language versions);
  • shell (start the shell);
  • brainfuck bench (build and run Brainfuck bench.b benchmarks);
  • brainfuck mandel (build and run Brainfuck mandel.b benchmarks);
  • base64 (build and run Base64 benchmarks);
  • json (build and run Json benchmarks);
  • matmul (build and run Matmul benchmarks);

Please note that the actual measurements provided in the project are taken semi-manually (via shell) as the full update takes days and could have occassional issues in Docker.

There is a Makefile that could be used to simlify Docker usage:

  • make build (build the image);
  • make versions (run the image with the versions command);
  • make shell (run the image with the `shell' command);
  • make toc (utility rule to update ToC in this README, requires git-markdown-toc available in PATH).

Please note that the make shell rule requires cpupower utility installed that is invoked with sudo to set cpufreq's performance governon (it runs the CPU at the maximum frequence to eliminate throttling issues).

Manual Execution

Makefiles contain recipes for building and executing tests with the proper dependencies. Please use make run (and make run2 where applicable). The measurements are taken using analyze.rb script:

$ cd <test suite>
$ ../analyze.rb make run
$ ../analyze.rb make run[<single test>]

Please note that the measurements could take hours. It uses 10 iterations by default, but it could be changed using ATTEMPTS environment variable:

$ ATTEMPTS=1 ../analyze.rb make run

Prerequisites

Please use Dockerfile as a reference regarding which packages and tools are required.

For all (optional):

  • Powercap for reading energy counters in Linux (Debian package powercap-utils).

For Python:

  • NumPy for matmul tests (Debian package python3-numpy).
  • UltraJSON for JSON tests (Debian package python3-ujson).

For C++:

  • Boost for JSON tests (Debian package libboost-dev).
  • JSON-C for JSON tests (Debian package libjson-c-dev).

For Rust:

  • libjq for jq test (Debian packages libjq-dev, libonig-dev and environment variable JQ_LIB_DIR=/usr/lib/x86_64-linux-gnu/).

For Java, Scala:

  • Coursier for downloading Maven artifacts.

For Lua:

  • LuaRocks for installing dependencies (Debian package luarocks).

For Haskell:

  • network for TCP connectivity between the tests and the test runner.
  • raw-strings-qq for raw string literals used in tests.

For Perl:

  • cpanminus for installing modules from CPAN (Debian package cpanminus).

For Vala:

  • JSON-GLib for JSON tests (Debian package libjson-glib-dev).

Contribution

Please follow the criteria specified in the overview. Besides that please ensure that the communication protocol between a test and the test runner is satisfied:

  • The test runner listens on localhost:9001;
  • All messages are sent using TCP sockets closed immediately after the message has been sent;
  • There are two messages sent from a test (it establishes the measurement boundary):
    1. The beginning message having the format name of the test/tprocess ID (the process ID is used to measure the memory consumption). Please note that the name of the test couldn't use Tab character as it's a delimiter;
    2. The end message with any content (mostly it's "stop" for consistency).
  • The test runner could be unavailable (if the test is launched as is) and the test should gracefully handle it.

Makefile guide

Binary executables

If the test is compiled into a single binary, then two sections of the Makefile require changes:

  • append a new target (the final binary location) into executables variable;
  • append the proper target rule.

Compiled artifacts

If the test is compiled, but can't be executed directly as a binary, then three sections of the Makefile require changes:

  • append a new target (the final artifact location) into artifacts variable;
  • append the proper target rule to compile the test;
  • append run[<target_artifact>] rule to run the test.

Scripting language

If the test doesn't require compilation, then two sections of the Makefile requires changes:

  • append run[<script_file>] into all_runners variable;
  • append run[<script_file>] rule to run the test.

About

Some benchmarks of different languages

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 9.5%
  • Makefile 9.5%
  • Ruby 5.5%
  • Java 5.3%
  • Rust 5.1%
  • C# 4.7%
  • Other 60.4%