Think twice before using double splat in Ruby

Prem Sichanugrist
Sikachu's Blog
Published in
1 min readJul 4, 2018

--

As of Ruby 2.5.1, double splat operator (**options, for example) is still considerably slower than accepting a normal argument and sets a default to empty hash.

Here’s a simple benchmark:

require "benchmark/ips"

def option_hash(options = {}); end
def double_splat(**options); end

Benchmark.ips do |x|
x.report("option_hash") { option_hash(foo: 1, bar: 2) }
x.report("double_splat") { double_splat(foo: 1, bar: 2) }
end

… and result (bigger number is better):

Warming up --------------------------------------
option_hash 123.232k i/100ms
double_splat 61.146k i/100ms
Calculating -------------------------------------
option_hash 1.798M (± 3.6%) i/s - 8.996M in 5.011461s
double_splat 708.545k (± 5.4%) i/s - 3.546M in 5.020927s

What’s the optimal usage of double splat?

You should use double splat in the method definition only if that method defines optional arguments.

# This is a valid use case since otherwise Ruby will set a hash
# in argument name `optional`.
def valid_use_of_double_splat(optional = nil, **options)
# Both of these use case can just use `options = {}`
def perform_delivery(recipient:, **options)
def associate_user(user, **options)

--

--

Senior Developer at Degica. I also contribute to open source projects, mostly in Ruby.