Skip to content

9il/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-03-31

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.869±0.026 1.49±00.00 + 0.00±00.00 17.64±00.80
Racket (Syntax Objects) 1.359±0.026 110.04±00.14 + 0.00±00.00 30.17±02.55
Rust 1.747±0.026 2.05±00.04 + 0.00±00.00 38.90±00.97
D/ldc2 1.760±0.063 3.03±00.04 + 0.00±00.00 37.80±02.69
C/gcc 1.801±0.049 0.50±00.01 + 0.00±00.00 40.08±01.11
Kotlin 1.801±0.037 38.80±00.08 + 1.55±00.05 33.84±01.23
Nim/gcc 1.883±0.037 1.87±00.06 + 0.00±00.00 35.48±01.09
D/gdc 1.973±0.054 6.21±00.07 + 0.00±00.00 36.87±01.67
Nim/clang 2.029±0.017 2.31±00.02 + 0.00±00.00 38.04±01.06
Racket 2.177±0.067 115.81±00.28 + 2.06±00.26 46.44±04.18
C/clang 2.215±0.026 0.50±00.00 + 0.00±00.00 44.48±02.20
Java 2.218±0.035 38.11±00.38 + 1.15±00.44 40.62±00.80
OCaml 2.220±0.094 2.61±00.05 + 2.51±00.06 44.80±03.57
Vala/gcc 2.233±0.016 3.75±00.04 + 0.00±00.00 48.63±00.41
Go 2.235±0.083 3.52±00.03 + 0.00±00.00 44.49±03.21
F#/.NET Core 2.327±0.050 36.85±00.02 + 0.39±00.03 42.33±00.87
C#/.NET Core 2.365±0.029 34.32±00.07 + 0.01±00.00 44.26±00.24
Go/gccgo 2.385±0.171 21.22±00.55 + 0.00±00.00 49.82±06.85
Vala/clang 2.445±0.128 3.77±00.05 + 0.00±00.00 53.48±03.97
V/gcc 2.448±0.027 0.50±00.00 + 0.00±00.00 46.70±00.85
Crystal 2.519±0.106 3.37±00.01 + 0.00±00.00 48.58±04.11
MLton 2.603±0.026 1.41±00.03 + 0.25±00.00 63.72±00.63
Chez Scheme 2.797±0.035 24.89±00.04 + 4.17±00.03 64.46±01.42
V/clang 2.859±0.092 0.87±00.00 + 0.00±00.00 54.72±01.94
Julia 3.061±0.114 200.19±00.07 + 0.61±00.03 60.56±03.38
D/dmd 3.520±0.106 3.66±00.04 + 0.00±00.00 76.86±01.48
Scala 3.540±0.033 73.42±00.77 + 44.39±02.28 71.26±01.80
Node.js 3.979±0.169 29.37±00.04 + 3.04±00.02 85.86±06.41
C#/Mono 4.303±0.098 20.15±00.06 + 0.00±00.00 79.91±05.24
Haskell (MArray) 4.336±0.081 3.67±00.04 + 1.17±00.00 102.58±03.61
Lua/luajit 6.412±0.229 2.94±00.08 + 0.00±00.00 124.39±10.77
Ruby/truffleruby 9.842±0.389 251.05±00.06 + 751.21±17.20 235.12±08.18
Ruby/truffleruby (--jvm) 10.334±0.765 563.35±06.15 + 527.56±90.35 352.45±13.58
Python/pypy 15.089±0.154 63.10±00.03 + 45.42±00.05 309.13±03.52
Haskell 15.832±0.547 3.93±00.04 + 0.88±00.00 358.33±22.45
Ruby (--jit) 57.981±1.755 14.06±00.06 + 0.23±00.00 1168.59±88.86
Lua 58.537±0.243 3.01±00.04 + 0.00±00.00 1104.39±09.98
Ruby 88.135±4.503 14.02±00.04 + 0.00±00.00 1829.33±99.56
Ruby/jruby 101.699±3.872 202.58±04.58 + 148.40±05.02 2061.38±76.31
Elixir 114.287±2.093 56.70±01.01 + 0.00±00.00 2557.73±92.41
Python 226.544±5.674 10.44±00.01 + 0.00±00.00 4744.63±300.21
Tcl (FP) 270.504±2.277 4.23±00.06 + 0.00±00.00 5930.55±310.39
Perl 357.665±9.538 6.52±00.07 + 0.00±00.00 7318.76±401.40
Tcl (OOP) 537.000±14.265 4.28±00.03 + 0.00±00.00 11271.28±673.92

mandel.b

Mandel in Brainfuck

Language Time, s Memory, MiB Energy, J
C/gcc 12.383±0.348 0.50±00.00 + 1.13±00.00 270.70±08.07
C++/g++ 12.992±0.578 1.50±00.01 + 2.16±00.04 274.10±18.31
Rust 13.011±0.460 2.04±00.07 + 0.25±00.00 276.11±17.34
D/ldc2 13.292±0.387 3.05±00.04 + 0.77±00.00 279.58±13.52
D/gdc 13.633±0.362 6.61±00.07 + 0.52±00.00 283.07±16.67
V/gcc 14.633±0.254 1.17±00.66 + 1.33±00.56 265.64±07.53
Kotlin 15.867±0.777 38.79±00.07 + 1.86±00.17 323.60±25.09
Nim/gcc 15.904±0.191 1.84±00.04 + 0.51±00.00 361.97±11.82
Racket (Syntax Objects) 16.212±0.257 109.92±00.07 + 70.90±00.13 371.05±13.45
Go 16.522±0.483 3.46±00.06 + 1.28±00.01 315.59±23.17
C/clang 18.029±0.435 0.50±00.00 + 1.13±00.01 342.99±03.97
C#/.NET Core 18.246±0.654 34.30±00.10 + 1.00±00.00 365.05±36.17
V/clang 20.060±0.249 0.90±00.04 + 2.01±00.14 376.36±18.04
Nim/clang 20.566±0.634 2.33±00.05 + 0.51±00.00 418.74±31.06
Java 20.839±0.898 38.23±00.13 + 1.36±00.12 440.21±16.34
Vala/gcc 20.914±0.228 0.00±00.00 + 0.00±00.00 459.53±19.89
Vala/clang 21.290±0.799 0.00±00.00 + 0.00±00.00 455.16±34.67
Scala 22.897±0.563 72.32±00.22 + 26.75±01.40 516.08±19.78
Crystal 23.608±0.416 3.33±00.04 + 0.40±00.02 539.40±15.54
Go/gccgo 24.522±0.908 21.14±00.31 + 1.29±00.00 488.16±34.77
F#/.NET Core 33.330±1.009 36.77±00.04 + 2.09±00.04 681.90±52.56
OCaml 38.006±0.753 3.88±00.01 + 9.91±02.58 717.17±20.45
Racket 38.550±1.518 116.04±00.23 + 1.68±00.13 750.19±34.12
Chez Scheme 38.818±0.638 25.46±00.04 + 3.65±00.02 910.22±23.50
C#/Mono 43.721±0.335 20.25±00.11 + 0.89±00.00 969.42±28.34
D/dmd 46.476±0.750 3.63±00.02 + 0.77±00.00 893.25±39.57
Node.js 46.617±0.270 29.34±00.07 + 5.59±00.07 851.80±15.55
MLton 50.512±0.466 1.44±00.03 + 4.11±00.00 1146.03±39.15
Haskell (MArray) 59.919±0.420 3.64±00.04 + 2.68±00.00 1372.34±22.61
Python/pypy 65.541±0.416 63.29±00.08 + 45.95±00.07 1543.03±13.74
Julia 77.758±0.837 200.70±00.17 + 0.64±00.03 1465.14±25.78
Ruby/truffleruby (--jvm) 127.673±2.631 567.51±03.09 + 460.57±11.26 2748.11±26.80
Ruby/truffleruby 166.906±3.606 251.32±00.11 + 764.61±05.09 3378.39±183.24
Haskell 210.405±3.191 3.88±00.07 + 26.16±00.00 4662.28±238.57
Lua/luajit 235.639±2.049 2.89±00.04 + 0.86±00.00 5308.03±75.14

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.153±0.002 1.91±00.01 + 0.00±00.00 3.58±00.07
Rust 1.163±0.016 2.54±00.05 + 0.01±00.00 23.27±01.58
C/gcc 1.179±0.014 1.91±00.04 + 0.00±00.00 23.10±01.62
V/gcc 1.570±0.072 1.49±00.01 + 0.64±00.05 29.90±02.52
Crystal 1.592±0.007 3.77±00.04 + 1.82±00.04 37.17±00.21
Nim/clang 1.792±0.027 2.73±00.03 + 4.44±00.03 32.45±00.45
V/clang 1.876±0.048 2.01±00.03 + 0.48±00.05 34.20±00.85
Nim/gcc 1.947±0.012 2.21±00.04 + 4.44±00.00 45.11±00.74
D/ldc2 1.964±0.017 3.47±00.04 + 3.67±00.00 35.71±00.39
D/gdc 2.014±0.088 6.94±00.06 + 3.40±00.01 41.01±03.52
Vala/clang 2.045±0.013 0.00±00.00 + 0.00±00.00 46.59±00.56
Vala/gcc 2.097±0.078 0.00±00.00 + 0.00±00.00 43.87±04.60
Java 2.168±0.028 38.77±00.57 + 292.57±09.58 49.56±01.80
Ruby 2.260±0.044 14.44±00.07 + 56.96±01.09 52.10±01.34
Ruby (--jit) 2.277±0.044 14.45±00.04 + 57.15±01.26 54.06±01.35
Kotlin 2.340±0.073 39.65±00.09 + 324.10±06.73 52.17±02.65
C++/g++ (libcrypto) 2.437±0.042 5.40±00.02 + 0.07±00.00 55.85±02.79
Scala 2.481±0.027 72.77±00.72 + 53.74±00.71 47.64±01.32
Go 2.577±0.007 4.60±00.02 + 5.39±00.18 47.73±00.23
Perl (MIME::Base64) 3.011±0.065 14.11±00.05 + 0.02±00.00 54.11±02.29
Node.js 3.012±0.042 29.81±00.03 + 1029.18±00.09 61.62±02.69
PHP 3.138±0.012 15.75±00.09 + 0.00±00.00 55.64±00.51
Go/gccgo 3.511±0.006 21.92±00.07 + 7.32±00.08 72.72±01.09
Python 3.773±0.019 10.14±00.02 + 0.18±00.00 86.88±01.61
D/dmd 3.796±0.063 3.75±00.07 + 3.67±00.06 67.42±01.89
Tcl 4.490±0.060 4.80±00.10 + 0.19±00.01 100.65±02.32
Python/pypy 4.958±0.117 63.26±00.03 + 45.74±00.03 87.84±01.85
F#/.NET Core 5.444±0.095 37.08±00.01 + 36.06±08.40 102.98±04.55
C#/.NET Core 5.743±0.018 34.61±00.11 + 45.08±03.51 109.02±00.99
Ruby/truffleruby (--jvm) 5.981±0.126 563.95±05.11 + 298.42±40.13 118.70±03.89
Julia 6.196±0.182 230.53±00.16 + 63.93±00.07 125.55±07.91
C#/Mono 7.623±0.027 20.73±00.04 + 18.48±00.03 145.13±01.95
Ruby/jruby 10.310±0.514 188.91±04.86 + 136.05±03.99 220.35±16.58
Perl (MIME::Base64::Perl) 16.248±0.556 15.50±00.07 + 0.20±00.07 341.96±31.97
Ruby/truffleruby 21.205±0.687 241.12±00.59 + 418.93±00.56 430.14±34.34

Json

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

NOTE: DAW JSON Link NoCheck doesn't perform JSON structure correctness checks.

NOTE: DAW JSON Link, gason, 'fast', default (not Pricese) RapidJSON, and D implementations except Mir-based have inaccurate IEEE incompatible number parsing.

NOTE: gason mutates input strings.

NOTE: simdjson and 'fast' (D) require input strings with batch of trailing zeros: a special zero padding for SIMD instructions.

Json

Language Time, s Memory, MiB Energy, J
C++/g++ (DAW JSON Link NoCheck) 0.079±0.001 112.82±00.23 + 0.00±00.00 2.24±00.04
C++/g++ (simdjson On-Demand) 0.081±0.002 109.87±00.03 + 59.55±00.00 1.86±00.11
D/gdc (fast) 0.099±0.002 219.96±00.07 + 11.34±00.00 2.44±00.17
C++/g++ (DAW JSON Link) 0.114±0.002 112.64±00.03 + 0.00±00.00 3.25±00.10
Rust (Serde Typed) 0.125±0.004 108.53±00.05 + 11.77±00.26 3.01±00.16
Rust (Serde Custom) 0.133±0.002 108.38±00.05 + 0.00±00.00 2.53±00.12
C++/g++ (simdjson DOM) 0.148±0.004 109.88±00.04 + 176.60±00.00 3.69±00.23
C++/g++ (gason) 0.159±0.001 109.21±00.01 + 97.17±00.03 3.02±00.09
C++/g++ (RapidJSON) 0.221±0.006 109.24±00.01 + 128.82±00.00 4.56±00.48
D/ldc2 (Mir Amazon's Ion DOM) 0.231±0.003 109.38±00.07 + 16.11±00.01 4.86±00.12
D/ldc2 (Mir Asdf DOM) 0.238±0.005 109.45±00.04 + 57.83±00.00 4.92±00.27
C++/g++ (RapidJSON Precise) 0.283±0.003 113.09±00.03 + 128.71±00.06 6.70±00.11
C++/g++ (Boost.JSON) 0.498±0.009 109.81±00.03 + 435.70±00.00 10.00±00.67
Java 0.508±0.007 253.80±00.21 + 70.03±01.09 13.87±00.33
C++/g++ (RapidJSON SAX) 0.530±0.008 109.44±00.02 + 0.00±00.00 11.80±00.31
Scala 0.589±0.011 307.27±00.60 + 74.61±00.32 14.93±00.66
C++/g++ (RapidJSON SAX Precise) 0.600±0.008 112.90±00.03 + 0.00±00.00 14.76±00.25
Node.js 0.632±0.026 242.44±00.02 + 185.01±00.27 15.47±01.24
Go (jsoniter) 0.653±0.014 224.31±00.14 + 13.69±00.22 14.46±00.73
Crystal (Schema) 0.783±0.008 110.38±00.03 + 46.88±00.11 12.28±00.20
Rust (Serde Untyped) 0.796±0.010 108.39±00.04 + 839.98±00.00 18.27±00.23
Crystal (Pull) 0.796±0.021 110.35±00.04 + 18.24±00.02 12.41±00.16
Python/pypy 0.798±0.031 276.56±00.05 + 127.96±00.00 17.11±01.65
V/clang 0.829±0.011 108.35±00.02 + 484.14±00.06 15.42±00.61
V/gcc 0.857±0.009 107.64±00.26 + 484.30±00.21 20.14±00.74
Julia (JSON3) 0.881±0.014 388.56±05.34 + 356.37±01.07 20.51±00.45
Perl (Cpanel::JSON::XS) 0.949±0.024 121.29±00.05 + 402.72±00.00 21.81±01.24
C#/.NET Core (System.Text.Json) 0.969±0.028 465.40±00.09 + 135.69±00.00 23.44±00.51
Crystal 1.055±0.035 110.32±00.08 + 393.34±00.02 19.27±00.67
Go 1.143±0.032 113.77±00.07 + 83.23±00.08 20.41±00.39
PHP 1.196±0.016 121.52±00.13 + 682.01±00.00 25.31±00.62
C++/g++ (json-c) 1.450±0.021 109.39±00.03 + 1216.07±00.00 34.03±00.76
Nim/gcc (Packedjson) 1.456±0.049 108.80±00.01 + 290.55±00.00 31.80±02.20
Nim/clang (Packedjson) 1.466±0.033 109.27±00.02 + 290.55±00.00 33.38±02.31
Go/gccgo 1.495±0.023 132.58±00.29 + 95.95±00.18 26.33±00.47
Clojure 1.556±0.049 469.16±04.90 + 621.88±14.07 41.43±02.27
C#/.NET Core 1.696±0.045 474.30±00.10 + 288.66±00.06 31.59±01.35
Python 1.736±0.044 116.73±00.01 + 377.21±00.00 37.67±02.41
CPython (UltraJSON) 1.758±0.036 118.43±00.03 + 545.83±02.36 38.09±01.08
Haskell 1.856±0.018 4.70±00.10 + 5.02±00.03 34.28±00.63
Nim/gcc 1.904±0.042 108.78±00.04 + 919.36±00.00 35.23±00.52
Nim/clang 1.918±0.024 109.19±00.05 + 919.42±00.06 35.93±01.38
C#/Mono 2.060±0.055 462.41±00.12 + 0.18±00.00 46.42±03.45
C++/g++ (Nlohmann) 2.173±0.030 109.33±00.01 + 448.31±00.00 43.76±00.42
D/gdc 2.227±0.080 113.16±00.06 + 600.28±00.00 49.11±01.80
Ruby 2.286±0.056 120.58±00.03 + 410.67±00.01 43.07±01.79
Ruby (YAJL) 2.300±0.082 120.54±00.02 + 281.58±00.00 48.46±03.87
Ruby (--jit) 2.335±0.039 120.62±00.01 + 410.78±00.01 45.49±01.11
F#/.NET Core (System.Text.Json) 2.526±0.051 471.70±00.09 + 444.59±02.96 46.50±00.91
D/ldc2 2.541±0.050 109.54±00.09 + 680.29±00.02 49.03±01.87
Rust (jq) 3.587±0.033 110.40±00.02 + 774.21±00.64 75.45±03.74
Ruby/jruby 3.641±0.138 466.71±05.85 + 1379.71±38.93 98.45±07.39
C++/g++ (Boost.PropertyTree) 4.423±0.178 109.56±00.06 + 1440.06±00.00 97.00±07.24
D/dmd 4.910±0.071 110.14±00.04 + 680.23±00.04 99.16±03.16
Vala/clang 5.199±0.194 0.00±00.00 + 0.00±00.00 107.75±09.21
Vala/gcc 5.574±0.040 0.00±00.00 + 0.00±00.00 101.91±02.17
Perl (JSON::Tiny) 11.829±0.286 121.94±00.07 + 525.12±00.04 245.67±18.39
Ruby/truffleruby (--jvm) 18.258±0.459 735.70±12.50 + 1571.42±34.39 490.21±05.42
Ruby/truffleruby 40.868±0.786 732.58±00.25 + 2351.77±120.46 916.47±58.11

Matmul

Testing allocating and multiplying matrices.

Matmul

Language Time, s Memory, MiB Energy, J
D/ldc2 (lubeck) 0.060±0.001 6.71±00.07 + 55.45±00.17 3.45±00.02
Python (NumPy) 0.094±0.001 27.66±00.09 + 57.68±00.03 5.36±00.09
Nim/clang (Arraymancer) 0.147±0.041 6.51±00.06 + 57.42±00.01 7.35±01.78
Nim/gcc (Arraymancer) 0.167±0.011 5.78±00.04 + 57.66±00.02 8.97±00.55
C++/g++ (Eigen) 0.186±0.003 3.54±00.03 + 85.25±00.00 3.76±00.03
Java (ND4J) 0.220±0.013 144.24±01.82 + 87.51±00.10 9.75±00.49
Julia (threads: 8) 0.293±0.003 238.60±00.19 + 30.86±00.23 15.18±00.33
Julia (threads: 1) 0.632±0.005 238.50±00.24 + 31.28±00.17 11.72±00.30
Julia (no BLAS) 1.144±0.014 217.53±00.18 + 51.52±00.00 32.78±01.92
D/ldc2 1.960±0.006 3.60±00.02 + 70.11±00.00 44.05±00.87
D/dmd 2.092±0.007 3.55±00.04 + 70.12±00.00 46.98±00.40
D/gdc 2.137±0.044 6.64±00.08 + 70.71±00.00 45.60±00.88
Java 3.304±0.007 38.96±00.19 + 80.65±00.49 74.63±00.99
C/gcc 3.307±0.009 2.04±00.06 + 68.06±00.00 76.20±01.67
Vala/gcc 3.336±0.006 0.00±00.00 + 0.00±00.00 67.47±01.18
Scala 3.356±0.049 74.48±00.12 + 74.42±03.95 77.03±00.89
Vala/clang 3.430±0.006 0.00±00.00 + 0.00±00.00 72.64±00.29
Nim/gcc 3.435±0.014 2.58±00.05 + 71.29±01.16 71.30±01.11
Nim/clang 3.473±0.011 3.08±00.05 + 75.54±04.77 71.60±01.04
Rust 3.519±0.062 2.62±00.06 + 68.32±00.00 69.38±01.98
Go 3.572±0.018 3.85±00.06 + 73.33±00.18 76.52±01.11
Go/gccgo 3.628±0.054 21.31±00.19 + 72.99±00.12 75.17±00.55
Crystal 3.637±0.022 4.18±00.12 + 59.66±00.06 78.60±01.31
Swift 3.694±0.083 149.00±00.05 + 59.61±00.14 83.34±04.81
V/clang 3.724±0.041 2.43±00.03 + 68.84±00.00 72.42±00.88
Node.js 3.759±0.033 32.61±00.12 + 71.54±00.52 87.65±01.63
V/gcc 4.503±0.195 1.97±00.03 + 68.84±00.00 90.31±09.35
Kotlin 4.679±0.044 38.06±00.15 + 81.76±00.44 84.14±02.52
Python/pypy 6.009±0.117 63.57±00.05 + 69.19±00.03 136.97±07.06
C#/.NET Core 7.288±0.069 33.94±00.09 + 69.14±00.03 127.95±02.59
C#/Mono 10.932±0.482 20.16±00.05 + 69.02±00.03 223.53±26.05
Ruby/truffleruby 50.394±0.352 523.19±00.38 + 740.58±02.09 1028.56±24.84
Ruby/truffleruby (--jvm) 70.186±1.667 616.78±05.98 + 388.84±31.46 1909.49±118.30
Ruby 215.251±5.288 15.17±00.07 + 68.64±00.00 4613.14±297.52
Ruby (--jit) 217.599±4.770 15.19±00.04 + 68.93±00.00 4331.21±327.51
Python 228.084±1.992 10.49±00.02 + 68.58±00.00 5019.49±156.86
Tcl 360.078±7.343 7.24±00.04 + 400.44±00.03 7082.90±189.15
Perl 401.651±3.072 9.02±00.04 + 599.67±00.08 8472.06±125.86
Ruby/jruby 498.988±15.692 276.05±05.82 + 983.96±46.89 10919.65±202.22

Primes

Testing:

Primes

Language Time, s Memory, MiB Energy, J
Scala 0.885±0.030 73.33±00.95 + 246.63±04.99 27.42±00.37
C++/g++ 0.970±0.006 1.49±00.00 + 172.00±00.02 18.24±00.24
Python/pypy 1.419±0.012 64.51±00.08 + 224.43±00.04 31.85±01.61
Node.js 1.746±0.007 30.83±00.06 + 307.78±00.35 39.25±00.73
Python 4.703±0.162 9.61±00.03 + 327.60±00.26 98.40±06.32

Tests Execution

Environment

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

Base Docker image: Debian GNU/Linux bullseye/sid

Language Version
.NET Core 5.0.104
C#/.NET Core 3.8.0-5.20604.10 (9ed4b774)
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.0
D/gdc 10.2.1
D/ldc2 1.25.1
Elixir 1.10.3
F#/.NET Core 11.0.0.0 for F# 5.0
Go go1.16.2
Go/gccgo 10.2.1
Haskell 8.10.4
Java 16
Julia v"1.6.0"
Kotlin 1.4.31
Lua Lua 5.4
Lua/luajit LuaJIT 2.1.0-beta3
MLton 20210117
Nim 1.4.4
Node.js v15.12.0
OCaml 4.11.1
PHP 7.4.15
Perl v5.32.1
Python 3.9.2
Python/pypy 7.3.3-beta0 for Python 3.7.9
Racket "8.0"
Ruby 3.0.0p0
Ruby/jruby 9.2.16.0
Ruby/truffleruby 21.0.0.2
Rust 1.51.0
Scala 2.13.5
Swift swift-5.3.3-RELEASE
Tcl 8.6
V 0.2.2
Vala 0.48.14

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

  • Makefile 9.9%
  • C++ 9.6%
  • Ruby 5.6%
  • C# 4.8%
  • D 4.7%
  • C 4.5%
  • Other 60.9%