ruby/benchmark
Jean Boussier aed0114913 [ruby/json] Annotate the encoding benchmark
Note where we currently stand, what the current bottlencks are
and what could or can't be done.

```
== Encoding small nested array (121 bytes)
ruby 3.3.4 (2024-07-09 revision https://github.com/ruby/json/commit/be1089c8ec) [arm64-darwin23]
Warming up --------------------------------------
                json   129.145k i/100ms
        json (reuse)   239.395k i/100ms
                  oj   211.514k i/100ms
           rapidjson   130.660k i/100ms
Calculating -------------------------------------
                json      1.284M (± 0.3%) i/s  (779.11 ns/i) -      6.457M in   5.030954s
        json (reuse)      2.405M (± 0.1%) i/s  (415.77 ns/i) -     12.209M in   5.076202s
                  oj      2.118M (± 0.0%) i/s  (472.11 ns/i) -     10.787M in   5.092795s
           rapidjson      1.325M (± 1.3%) i/s  (754.82 ns/i) -      6.664M in   5.030763s

Comparison:
                json:  1283514.8 i/s
        json (reuse):  2405175.0 i/s - 1.87x  faster
                  oj:  2118132.9 i/s - 1.65x  faster
           rapidjson:  1324820.8 i/s - 1.03x  faster

== Encoding small hash (65 bytes)
ruby 3.3.4 (2024-07-09 revision https://github.com/ruby/json/commit/be1089c8ec) [arm64-darwin23]
Warming up --------------------------------------
                json   177.502k i/100ms
        json (reuse)   485.963k i/100ms
                  oj   656.566k i/100ms
           rapidjson   227.985k i/100ms
Calculating -------------------------------------
                json      1.774M (± 3.1%) i/s  (563.67 ns/i) -      8.875M in   5.007964s
        json (reuse)      4.804M (± 3.0%) i/s  (208.16 ns/i) -     24.298M in   5.062426s
                  oj      6.564M (± 1.9%) i/s  (152.36 ns/i) -     32.828M in   5.003539s
           rapidjson      2.229M (± 2.0%) i/s  (448.59 ns/i) -     11.171M in   5.013299s

Comparison:
                json:  1774084.6 i/s
                  oj:  6563547.8 i/s - 3.70x  faster
        json (reuse):  4804083.0 i/s - 2.71x  faster
           rapidjson:  2229209.5 i/s - 1.26x  faster

== Encoding twitter.json (466906 bytes)
ruby 3.3.4 (2024-07-09 revision https://github.com/ruby/json/commit/be1089c8ec) [arm64-darwin23]
Warming up --------------------------------------
                json   212.000 i/100ms
                  oj   222.000 i/100ms
           rapidjson   109.000 i/100ms
Calculating -------------------------------------
                json      2.135k (± 0.7%) i/s  (468.32 μs/i) -     10.812k in   5.063665s
                  oj      2.219k (± 1.9%) i/s  (450.69 μs/i) -     11.100k in   5.004642s
           rapidjson      1.093k (± 3.8%) i/s  (914.66 μs/i) -      5.559k in   5.090812s

Comparison:
                json:     2135.3 i/s
                  oj:     2218.8 i/s - 1.04x  faster
           rapidjson:     1093.3 i/s - 1.95x  slower

== Encoding citm_catalog.json (500298 bytes)
ruby 3.3.4 (2024-07-09 revision https://github.com/ruby/json/commit/be1089c8ec) [arm64-darwin23]
Warming up --------------------------------------
                json   132.000 i/100ms
                  oj   126.000 i/100ms
           rapidjson    96.000 i/100ms
Calculating -------------------------------------
                json      1.304k (± 2.2%) i/s  (766.96 μs/i) -      6.600k in   5.064483s
                  oj      1.272k (± 0.8%) i/s  (786.14 μs/i) -      6.426k in   5.052044s
           rapidjson    997.370 (± 4.8%) i/s    (1.00 ms/i) -      4.992k in   5.016266s

Comparison:
                json:     1303.9 i/s
                  oj:     1272.0 i/s - same-ish: difference falls within error
           rapidjson:      997.4 i/s - 1.31x  slower

== Encoding canada.json (2090234 bytes)
ruby 3.3.4 (2024-07-09 revision https://github.com/ruby/json/commit/be1089c8ec) [arm64-darwin23]
Warming up --------------------------------------
                json     2.000 i/100ms
                  oj     3.000 i/100ms
           rapidjson     1.000 i/100ms
Calculating -------------------------------------
                json     20.001 (± 0.0%) i/s   (50.00 ms/i) -    102.000 in   5.100950s
                  oj     30.823 (± 0.0%) i/s   (32.44 ms/i) -    156.000 in   5.061333s
           rapidjson     19.446 (± 0.0%) i/s   (51.42 ms/i) -     98.000 in   5.041884s

Comparison:
                json:       20.0 i/s
                  oj:       30.8 i/s - 1.54x  faster
           rapidjson:       19.4 i/s - 1.03x  slower

== Encoding many #to_json calls (2661 bytes)
oj does not match expected output. Skipping
rapidjson unsupported (Invalid object key type: Object)
ruby 3.3.4 (2024-07-09 revision https://github.com/ruby/json/commit/be1089c8ec) [arm64-darwin23]
Warming up --------------------------------------
                json     2.200k i/100ms
Calculating -------------------------------------
                json     22.253k (± 0.2%) i/s   (44.94 μs/i) -    112.200k in   5.041962s
```

https://github.com/ruby/json/commit/77e97b3d4e
2024-10-26 18:44:15 +09:00
..
2024-10-16 07:11:03 +00:00
2023-03-06 22:36:57 -08:00
2024-09-13 14:35:25 +09:00
2024-07-08 12:24:33 +02:00
2024-04-15 11:29:48 -07:00
2024-10-08 14:18:37 +00:00
2023-02-28 10:05:30 -08:00
2024-10-03 21:20:09 +01:00
2023-11-20 14:33:20 +01:00
2024-09-23 14:29:25 +09:00
2023-04-25 08:06:16 -07:00
2023-04-25 08:06:16 -07:00

ruby/benchmark

This directory has benchmark definitions to be run with benchmark_driver.gem.

Normal usage

Execute gem install benchmark_driver and run a command like:

# Run a benchmark script with the ruby in the $PATH
benchmark-driver benchmark/app_fib.rb

# Run benchmark scripts with multiple Ruby executables or options
benchmark-driver benchmark/*.rb -e /path/to/ruby -e '/path/to/ruby --jit'

# Or compare Ruby versions managed by rbenv
benchmark-driver benchmark/*.rb --rbenv '2.5.1;2.6.0-preview2 --jit'

# You can collect many metrics in many ways
benchmark-driver benchmark/*.rb --runner memory --output markdown

# Some are defined with YAML for complex setup or accurate measurement
benchmark-driver benchmark/*.yml

See also:

Usage: benchmark-driver [options] RUBY|YAML...
    -r, --runner TYPE                Specify runner type: ips, time, memory, once, block (default: ips)
    -o, --output TYPE                Specify output type: compare, simple, markdown, record, all (default: compare)
    -e, --executables EXECS          Ruby executables (e1::path1 arg1; e2::path2 arg2;...)
        --rbenv VERSIONS             Ruby executables in rbenv (x.x.x arg1;y.y.y arg2;...)
        --repeat-count NUM           Try benchmark NUM times and use the fastest result or the worst memory usage
        --repeat-result TYPE         Yield "best", "average" or "worst" result with --repeat-count (default: best)
        --alternate                  Alternate executables instead of running the same executable in a row with --repeat-count
        --bundler                    Install and use gems specified in Gemfile
        --filter REGEXP              Filter out benchmarks with given regexp
        --run-duration SECONDS       Warmup estimates loop_count to run for this duration (default: 3)
        --timeout SECONDS            Timeout ruby command execution with timeout(1)
    -v, --verbose                    Verbose mode. Multiple -v options increase visilibity (max: 2)

make benchmark

Using make benchmark, make update-benchmark-driver automatically downloads the supported version of benchmark_driver, and it runs benchmarks with the downloaded benchmark_driver.

# Run all benchmarks with the ruby in the $PATH and the built ruby
make benchmark

# Or compare with specific ruby binary
make benchmark COMPARE_RUBY="/path/to/ruby --jit"

# Run vm benchmarks
make benchmark ITEM=vm

# Run some limited benchmarks in ITEM-matched files
make benchmark ITEM=vm OPTS=--filter=block

# You can specify the benchmark by an exact filename instead of using the default argument:
# ARGS = $$(find $(srcdir)/benchmark -maxdepth 1 -name '*$(ITEM)*.yml' -o -name '*$(ITEM)*.rb')
make benchmark ARGS=benchmark/erb_render.yml

# You can specify any option via $OPTS
make benchmark OPTS="--help"

# With `make benchmark`, some special runner plugins are available:
#   -r peak, -r size, -r total, -r utime, -r stime, -r cutime, -r cstime
make benchmark ITEM=vm_bigarray OPTS="-r peak"