-
-
Save nogtini/37fe2db0213d5a4a23802fa792159f84 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# How expensive is DCI in Ruby? | |
# http://news.ycombinator.com/item?id=4997498 | |
RUBY_VERSION # => "1.9.3" | |
RUBY_PATCHLEVEL # => 362 | |
RUBY_PLATFORM # => "x86_64-darwin12.2.0" | |
require 'benchmark' | |
require 'delegate' | |
require 'forwardable' | |
class C | |
def org; :org; end | |
def ovr; :org; end | |
end | |
class LazyDel < SimpleDelegator | |
def ldl; :ldl; end | |
def ovr; :ldl; end | |
end | |
class ForwDel | |
extend Forwardable | |
def initialize(base) | |
@base = base | |
end | |
delegate :org => :@base | |
def fwd; :fwd; end | |
def ovr; :fwd; end | |
end | |
class ExplDel | |
def initialize(base) | |
@base = base | |
end | |
def org | |
@base.org | |
end | |
def xdl; :xdl; end | |
def ovr; :xdl; end | |
end | |
module M | |
def ext; :ext; end | |
def ovr; :ext; end | |
end | |
N = 1_000_000 | |
objects = Hash.new { |hash, key| hash[key] = [] } | |
COLS = 8 | |
puts "create #{N} objects" | |
Benchmark.bm(COLS) do |bm| | |
bm.report("plain") do | |
N.times do | |
objects[:plain] << C.new | |
end | |
end | |
bm.report("lazy del") do | |
N.times do | |
objects[:lazy_del] << LazyDel.new(C.new) | |
end | |
end | |
bm.report("forw del") do | |
N.times do | |
objects[:forw_del] << ForwDel.new(C.new) | |
end | |
end | |
bm.report("expl del") do | |
N.times do | |
objects[:expl_del] << ExplDel.new(C.new) | |
end | |
end | |
bm.report("extend") do | |
N.times do | |
objects[:extend] << C.new.extend(M) | |
end | |
end | |
end | |
puts | |
puts "method call: delegate" | |
Benchmark.bm(COLS) do |bm| | |
objects.each do |key, value| | |
bm.report(key) { value.each { |o| o.org } } | |
end | |
end | |
puts | |
puts "method call: added" | |
Benchmark.bm(COLS) do |bm| | |
bm.report("plain") { objects[:plain].each { |o| o.org } } | |
bm.report("lazy del") { objects[:lazy_del].each { |o| o.ldl } } | |
bm.report("forw del") { objects[:forw_del].each { |o| o.fwd } } | |
bm.report("expl del") { objects[:expl_del].each { |o| o.xdl } } | |
bm.report("extend") { objects[:extend].each { |o| o.ext } } | |
end | |
puts | |
puts "method call: overloaded" | |
Benchmark.bm(COLS) do |bm| | |
objects.each do |key, value| | |
bm.report(key) { value.each { |o| o.ovr } } | |
end | |
end | |
# Conclusions | |
# - Creating objects will never be free. | |
# - Extending an object is **very** expensive. | |
# - Delegating using `SimpleDelegator` (`method_missing`) is expensive. | |
# - Delegating using explicit implementation is a bit cheaper than extending. | |
# - Adding and overloading methods by extending adds an overhead. | |
# >> create 1000000 objects | |
# >> user system total real | |
# >> plain 0.370000 0.040000 0.410000 ( 0.466573) | |
# >> lazy del 0.790000 0.060000 0.850000 ( 1.072003) | |
# >> forw del 0.560000 0.050000 0.610000 ( 0.915602) | |
# >> expl del 0.690000 0.060000 0.750000 ( 1.246730) | |
# >> extend 8.950000 0.390000 9.340000 ( 9.431121) | |
# >> | |
# >> method call: delegate | |
# >> user system total real | |
# >> plain 0.120000 0.000000 0.120000 ( 0.124878) | |
# >> lazy_del 0.760000 0.030000 0.790000 ( 0.800174) | |
# >> forw_del 0.420000 0.030000 0.450000 ( 0.454589) | |
# >> expl_del 0.200000 0.000000 0.200000 ( 0.200165) | |
# >> extend 0.300000 0.000000 0.300000 ( 0.324213) | |
# >> | |
# >> method call: added | |
# >> user system total real | |
# >> plain 0.130000 0.010000 0.140000 ( 0.134556) | |
# >> lazy del 0.130000 0.000000 0.130000 ( 0.134953) | |
# >> forw del 0.130000 0.000000 0.130000 ( 0.141292) | |
# >> expl del 0.130000 0.000000 0.130000 ( 0.128352) | |
# >> extend 0.260000 0.000000 0.260000 ( 0.259568) | |
# >> | |
# >> method call: overloaded | |
# >> user system total real | |
# >> plain 0.120000 0.000000 0.120000 ( 0.124404) | |
# >> lazy_del 0.130000 0.000000 0.130000 ( 0.126756) | |
# >> forw_del 0.120000 0.000000 0.120000 ( 0.126492) | |
# >> expl_del 0.130000 0.000000 0.130000 ( 0.127103) | |
# >> extend 0.270000 0.000000 0.270000 ( 0.272072) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment