Notes to self

How fast is Ruby 2.5, 2.6 and 2.6 –jit in generating Prawn PDFs

Takashi Kokubun (known as k0kubun), a Ruby JIT committer, asked the community for more benchmarks on upcoming Ruby 2.6 JIT. I put together one for generating PDF documents with InvoicePrinter (based on Prawn).

Making a JIT benchmark

To benchmark the code with and without JIT I used Takashi’s own gem benchmark_driver. The README will guide you on how to create a simple YAML file.

Since I don’t use rbenv as Takshi, but ruby-install and chruby, I just pass the executables with -e option (I even sent a patch some time ago for this option since I didn’t realize it’s there!).

However there was still one gotcha in handling the Ruby arguments. If you use old version of the gem you need to pass arguments after the executable path separated by comma (notice the ,--jit):

$ benchmark-driver benchmarks/render.yml -e '/home/strzibny/.rubies/ruby-2.6.0-preview3/bin/ruby;/home/strzibny/.rubies/ruby-2.6.0-preview3/bin/ruby,--jit'

This is now fixed in the latest versions so feel free to run it as:

$ benchmark-driver benchmarks/render.yml -e '/home/strzibny/.rubies/ruby-2.6.0-preview3/bin/ruby;/home/strzibny/.rubies/ruby-2.6.0-preview3/bin/ruby --jit'

I sent a patch to fix the README.

What’s been benchmarked?

In this blog post I am benchmarking the generation of a simple invoice using InvoicePrinter’s render method. It’s variant on this example. InvoicePrinter is based on Prawn PDF library.

I am running the benchmark on my Thinkpad X1 Carbon 5th generation with i7-7600U processor, 16 GB RAM and SSD. I already committed this benchmark to the InvoicePrinter repository, feel free to suggest improvements!

Results

Without further ado here is the graph:

As you can see Ruby 2.6 is a little bit better, but pretty much the same in iterations per second. Here is the text output for loop_count of 1000:

Comparison:
render
/home/strzibny/.rubies/ruby-2.6.0-preview3/bin/ruby:       100.4 i/s
/home/strzibny/.rubies/ruby-2.5.0/bin/ruby:        96.9 i/s - 1.04x  slower
/home/strzibny/.rubies/ruby-2.6.0-preview3/bin/ruby,--jit:        86.6 i/s - 1.16x  slower

And 10000:

Comparison:
render
/home/strzibny/.rubies/ruby-2.6.0-preview3/bin/ruby:        99.8 i/s
/home/strzibny/.rubies/ruby-2.5.0/bin/ruby:        95.8 i/s - 1.04x  slower
/home/strzibny/.rubies/ruby-2.6.0-preview3/bin/ruby,--jit:        64.5 i/s - 1.55x  slower

Comparison:
render
/home/strzibny/.rubies/ruby-2.5.0/bin/ruby: 106.1 i/s
/home/strzibny/.rubies/ruby-2.6.0-preview3/bin/ruby: 104.6 i/s - 1.01x slower
/home/strzibny/.rubies/ruby-2.6.0-preview3/bin/ruby --jit: 73.5 i/s - 1.44x slower

Depending on a run Ruby 2.6 can render here around 100 invoices per second. 4-5 more or less than 2.5. In other words it seems the performance is pretty much the same. The –jit version runs 1,1-1,6 times slower which is not yet great.

What about memory?

Comparison:
                           render
/home/strzibny/.rubies/ruby-2.5.0/bin/ruby:  18316000.0 bytes
/home/strzibny/.rubies/ruby-2.6.0-preview3/bin/ruby:  22812000.0 bytes - 1.25x  larger
/home/strzibny/.rubies/ruby-2.6.0-preview3/bin/ruby,--jit:  75672000.0 bytes - 4.13x  larger

Ruby 2.6 uses a little more memory than 2.5 on my example. The –jit version even 4 times as Ruby 2.5.

Feel free to run it yourself and report.

I hope this benchmark can help Takashi somehow and we see some improvements for JIT when using Prawn in future.

Check out my book
Deployment from Scratch is unique Linux book about web application deployment. Learn how deployment works from the first principles rather than YAML files of a specific tool.
by Josef Strzibny
RSS