Skip to content

Instantly share code, notes, and snippets.

@Spaceghost
Created December 16, 2014 18:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Spaceghost/faa04552950ddd6abe5b to your computer and use it in GitHub Desktop.
Save Spaceghost/faa04552950ddd6abe5b to your computer and use it in GitHub Desktop.

Benchmarking ruby

The problem: Create a hash from an array of objects where the key is the object's #id and the value is the #stuff method.

Known/Suspected caveats:

  • Garbage collection might be happening, making the results lie.
  • Not exhaustive of ways to create a hash from an array
  • Not exhaustive of ways to call Benchmark.ips with code to test. (no strings yet)
  • Not able to manually change the number of iterations
  • No GC instrumentation/profiling/timing
  • This is completely unfair, as I broke the original pattern of calling #inject to artificially 'boost' iterations.

When I started working on this benchmark, I didn't notice any GC stop-the-world time, but I'm human. The fastest was to use #each_with_object but it was only a hair faster than #inject with assign and return.

I realize there are lots of other ways to merge, but the slowest by far is to actually call #merge instead of #merge!. I intend to rewrite this to be more fair, but that might be pending a fork of benchmark/ips from evan phoenix.

require 'benchmark/ips'
User = Struct.new(:id, :stuff)
a = Array.new(1000) { |i| User.new(i, stuff: rand(1000)) }
10.times do
Benchmark.ips do |x|
x.report('#inject return') do
a.inject({}) { |memo, i| memo[i.id] = i.stuff; memo }
end
x.report('merge') do
a.inject({}) { |memo, i| memo.merge(i.id => i.stuff) }
end
x.report('merge!') do
a.inject({}) { |memo, i| memo.merge!(i.id => i.stuff) }
end
x.report('each_with_object') do
a.each_with_object({}) { |i, memo| memo[i.id] = i.stuff }
end
x.report('zenspider') do
Hash[a.map(&:to_a)]
end
x.report('pipework') do
a.map(&:to_a).to_h
end
x.compare!
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment