New Ruby versions keep improving & Ruby 2.5 is no different.
Ruby 2.5 introduces these optimizations:
- String interpolation will be around 72% faster when a large string is created
- String#prepend will be around 42% faster if only one argument is given
- Enumerable#sort_by, Enumerable#min_by & Enumerable#max_by will be about 50% faster
Let's see some benchmarks!
String Interpolation Performance
I took the example code in the commit message for this optimization:
require 'benchmark/ips' Benchmark.ips do |x| x.report "Large string interpolation" do |t| a = "Hellooooooooooooooooooooooooooooooooooooooooooooooooooo" b = "Wooooooooooooooooooooooooooooooooooooooooooooooooooorld" t.times { "#{a}, #{b}!" } end x.report "Small string interpolation" do |t| a = "Hello" b = "World" t.times { "#{a}, #{b}!" } end x.compare! end
I ran this benchmark with the following results.
Ruby 2.4.1:
Small string interpolation: 3236291.1 i/s Large string interpolation: 1711633.4 i/s - 1.89x slower
Ruby 2.5:
Small string interpolation: 3125175.1 i/s Large string interpolation: 2555782.6 i/s - 1.22x slower
As you can see the difference for large strings is pretty remarkable!
String#prepend Performance
The prepend method allows you to insert some text in front of an array.
Ruby 2.5 optimizes for the most common case, prepending only one string to another.
Here are the benchmark results.
Ruby 2.4.1 results:
String#prepend 3.428M (± 3.2%) i/s - 17.159M in 5.011008s
Ruby 2.5 results:
String#prepend 4.638M (± 3.6%) i/s - 23.276M in 5.025562s
That's a pretty good improvement!
Enumerable Performance Improvements
A few Enumerable methods are getting a performance upgrade.
This particular optimization works because it skips method dispatching for the <=>
method.
As described on the commit message:
"Use OPTIMIZED_CMP() to compare the objects instead of
<=>
method dispatching for Fixnum/Float/String object."
Here are my benchmark results.
Ruby 2.4.2:
Enumerable#sort_by 2.395k (± 6.7%) i/s - 11.952k in 5.014422s Enumerable#min_by 8.244k (± 6.1%) i/s - 41.405k in 5.042327s Enumerable#max_by 8.053k (± 6.7%) i/s - 40.180k in 5.015375s
Ruby 2.5:
Enumerable#sort_by 5.914k (± 6.7%) i/s - 29.786k in 5.062584s Enumerable#min_by 15.668k (± 3.0%) i/s - 78.888k in 5.039748s Enumerable#max_by 15.544k (± 2.3%) i/s - 78.408k in 5.046709s
That's about a 50% improvement 🙂
Range#min & Range#max
I have two bonus performance optimizations for you!
One is about the Range#min & Range#max methods.
Here are the benchmarks:
Ruby 2.4.2
Range#min 7.976M (± 3.0%) i/s - 39.950M in 5.013242s Range#max 7.996M (± 3.4%) i/s - 40.059M in 5.015984s
Ruby 2.5
Range#min 13.154M (± 3.0%) i/s - 65.731M in 5.002094s Range#max 13.021M (± 2.6%) i/s - 65.202M in 5.010924s
Find the commit here.
Improved String#scan
According to the commit message this improves performance by 50% for a string pattern & 10% for a regex pattern.
Let’s look at the benchmarks!
Ruby 2.4.2
String#scan - String pattern 1.367M (±19.8%) i/s - 6.458M in 4.982047s String#scan - Regex pattern 1.228M (±17.0%) i/s - 5.881M in 4.983943s
Ruby 2.5
String#scan - String pattern 3.944M (±24.4%) i/s - 17.739M in 4.977417s String#scan - Regex pattern 1.696M (±17.4%) i/s - 8.103M in 4.982614s
Happy faster scanning!
Summary
You learned about the new optimizations coming in Ruby 2.5, to be released on December 25.
These optimizations are about string interpolation, Enumerable methods, the String#prepend
method, the String#scan
method & the Range#max
/ Range#mix
methods.
I hope you enjoyed this post!
Don't forget to share the post on your favorite social networks 🙂
According to your benchmark, String#scan is slower in ruby-2.5. Is it a mistake?
Fixed. Sorry about that 🙂
Looks great! One thing… is the last example backwards?
Cheers!
Yes. It’s fixed now 🙂
I’d like to translate the article and publish on our blog if you’re OK.
I will make sure to indicate the link to original, author name, and your site.
Best regards,
Ok, you can do this. Only for this one article 🙂
Thank you for the permission!
(I should’ve requested for https://www.rubyguides.com/2017/10/7-powerful-ruby-methods/ …)
Published the JP translation https://techracho.bpsinc.jp/hachi8833/2017_11_20/48128
Thank you very much!