Skip to content

Instantly share code, notes, and snippets.

@copiousfreetime
Last active January 20, 2021 20:48
Show Gist options
  • Save copiousfreetime/150ba0193c020d89bc08a94ba2cb1da8 to your computer and use it in GitHub Desktop.
Save copiousfreetime/150ba0193c020d89bc08a94ba2cb1da8 to your computer and use it in GitHub Desktop.
send vs. method invocation benchmark comparison
% bundle exec ./send-bench.rb
Warming up --------------------------------------
native 973.581k i/100ms
symbol 476.433k i/100ms
string 355.763k i/100ms
frozen 417.573k i/100ms
constant-frozen 356.666k i/100ms
instance_eval 738.433k i/100ms
singleton_method 468.459k i/100ms
subclass 794.878k i/100ms
subclass2 591.266k i/100ms
Calculating -------------------------------------
native 9.189M (± 5.0%) i/s - 46.732M in 5.099022s
symbol 5.274M (±15.2%) i/s - 25.727M in 5.033201s
string 2.913M (±11.6%) i/s - 14.586M in 5.093338s
frozen 3.687M (± 5.7%) i/s - 18.791M in 5.113343s
constant-frozen 3.411M (±15.5%) i/s - 16.763M in 5.082502s
instance_eval 7.389M (±10.3%) i/s - 36.922M in 5.068440s
singleton_method 4.823M (± 8.2%) i/s - 24.360M in 5.091255s
subclass 7.408M (±13.1%) i/s - 36.564M in 5.059877s
subclass2 8.715M (± 9.6%) i/s - 43.754M in 5.071426s
Comparison:
native: 9188725.1 i/s
subclass2: 8714509.7 i/s - same-ish: difference falls within error
subclass: 7408254.5 i/s - 1.24x (± 0.00) slower
instance_eval: 7388878.9 i/s - 1.24x (± 0.00) slower
symbol: 5274300.3 i/s - 1.74x (± 0.00) slower
singleton_method: 4823225.5 i/s - 1.91x (± 0.00) slower
frozen: 3687469.2 i/s - 2.49x (± 0.00) slower
constant-frozen: 3411027.9 i/s - 2.69x (± 0.00) slower
string: 2913035.2 i/s - 3.15x (± 0.00) slower
#!/usr/bin/env ruby
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'benchmark-ips', require: 'benchmark/ips'
end
INCREMENT = "increment".freeze
class SendTest
attr_reader :count
def initialize(eval_method: nil, singleton_method: nil)
@count = 0
if eval_method then
instance_eval <<~RUBY
def #{eval_method}
increment
end
RUBY
end
if singleton_method then
self.define_singleton_method(singleton_method.to_sym) do
increment
end
end
end
def increment
@count += 1
end
def kaboom
raise "kaboom"
end
end
class Sub < SendTest
def incr2
increment
end
def incr3
@count += 1
end
end
# s1 = SendTest.new
# s2 = SendTest.new(create_alias: :other)
# puts "s1"
# s1.increment
# puts "s2"
# s2.other
Benchmark.ips do |x|
x.config(:time => 5, :warmup => 2)
x.report("native") do |times|
t = SendTest.new
times.times do |x|
t.increment
end
end
x.report("symbol") do |times|
t = SendTest.new
times.times do |x|
t.send(:increment)
end
end
x.report("string") do |times|
t = SendTest.new
times.times do |x|
t.send("increment")
end
end
x.report("frozen") do |times|
t = SendTest.new
frozen = "increment".freeze
times.times do |x|
t.send(frozen)
end
end
x.report("constant-frozen") do |times|
t = SendTest.new
times.times do |x|
t.send(INCREMENT)
end
end
x.report("instance_eval") do |times|
t = SendTest.new(eval_method: "do_increment")
times.times do |x|
t.do_increment
end
end
x.report("singleton_method") do |times|
t = SendTest.new(singleton_method: "singleton_increment")
times.times do |x|
t.singleton_increment
end
end
x.report("subclass") do |times|
t = Sub.new
times.times do |x|
t.incr2
end
end
x.report("subclass2") do |times|
t = Sub.new
times.times do |x|
t.incr3
end
end
x.compare!
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment