Skip to content

Instantly share code, notes, and snippets.

@avdi
Created February 25, 2015 00:51
Show Gist options
  • Save avdi/af5d7d84db9173a22f19 to your computer and use it in GitHub Desktop.
Save avdi/af5d7d84db9173a22f19 to your computer and use it in GitHub Desktop.
require "delegate"
class BankAccount
def number
123456
end
end
class SimpleDelegatorBankAccount < SimpleDelegator
end
class DelegateClassBankAccount < DelegateClass(BankAccount)
end
class ManualDelegatorBankAccount
def initialize(target)
@target = target
end
def number
@target.number
end
end
account = BankAccount.new
sdba = SimpleDelegatorBankAccount.new(account)
dcba = DelegateClassBankAccount.new(account)
mdba = ManualDelegatorBankAccount.new(account)
require "benchmark"
puts RUBY_VERSION
n = 1_000_000
Benchmark.bmbm(20) do |x|
x.report("direct call") do
n.times do
_ = account.number
end
end
x.report("manual delegation") do
n.times do
_ = mdba.number
end
end
x.report("SimpleDelegator") do
n.times do
_ = sdba.number
end
end
x.report("DelegateClass") do
n.times do
_ = dcba.number
end
end
end
# >> 2.2.0
# >> Rehearsal --------------------------------------------------------
# >> direct call 2.210000 0.020000 2.230000 ( 2.332280)
# >> manual delegation 3.410000 0.070000 3.480000 ( 3.500194)
# >> SimpleDelegator 2.850000 0.060000 2.910000 ( 2.920977)
# >> DelegateClass 3.370000 0.020000 3.390000 ( 3.411052)
# >> ---------------------------------------------- total: 12.010000sec
# >>
# >> user system total real
# >> direct call 1.800000 0.030000 1.830000 ( 1.834531)
# >> manual delegation 2.830000 0.130000 2.960000 ( 2.958950)
# >> SimpleDelegator 2.960000 0.040000 3.000000 ( 3.038120)
# >> DelegateClass 2.390000 0.030000 2.420000 ( 2.878221)
@ka8725
Copy link

ka8725 commented Feb 25, 2015

The results look artificial. These are my results (n = 10_000_000):

2.2.0
Rehearsal --------------------------------------------------------
direct call            1.240000   0.020000   1.260000 (  1.340032)
manual delegation      2.280000   0.030000   2.310000 (  2.665107)
SimpleDelegator        7.350000   0.110000   7.460000 (  7.911528)
DelegateClass          6.780000   0.100000   6.880000 (  7.615661)
---------------------------------------------- total: 17.910000sec

                           user     system      total        real
direct call            1.350000   0.020000   1.370000 (  1.505028)
manual delegation      2.380000   0.040000   2.420000 (  2.777522)
SimpleDelegator        7.450000   0.120000   7.570000 (  8.201753)
DelegateClass          6.690000   0.100000   6.790000 (  7.798169)

@avsej
Copy link

avsej commented Feb 25, 2015

Yeah, that's strange, in my setup manual delegation beats everything else. @avdi could you post your config options?

2.1.5
Rehearsal --------------------------------------------------------
direct call            0.060000   0.000000   0.060000 (  0.051810)
manual delegation      0.070000   0.000000   0.070000 (  0.069584)
SimpleDelegator        0.290000   0.000000   0.290000 (  0.292204)
DelegateClass          0.240000   0.000000   0.240000 (  0.240766)
----------------------------------------------- total: 0.660000sec

                           user     system      total        real
direct call            0.050000   0.000000   0.050000 (  0.050323)
manual delegation      0.070000   0.000000   0.070000 (  0.069290)
SimpleDelegator        0.290000   0.000000   0.290000 (  0.285019)
DelegateClass          0.240000   0.000000   0.240000 (  0.240112)
$ ruby -rrbconfig -e"puts RbConfig::CONFIG['cflags']"
 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration

@avdi
Copy link
Author

avdi commented Feb 25, 2015

@avsej here are my options:

-O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration

@ka8725: You got me, I have nothing better to do with my time than manufacture fake benchmark results for no reason :-P

Seriously, I've had several people come up with different results from me and I'm at a loss as to why mine are so different. Would love to figure it out.

@avdi
Copy link
Author

avdi commented Feb 25, 2015

OK, I have no idea what was going on with those earlier results. Here's what I'm getting now:

2.2.0
Rehearsal --------------------------------------------------------
direct call            0.110000   0.000000   0.110000 (  0.113840)
manual delegation      0.130000   0.000000   0.130000 (  0.125471)
SimpleDelegator        0.340000   0.000000   0.340000 (  0.342948)
DelegateClass          0.360000   0.000000   0.360000 (  0.357626)
----------------------------------------------- total: 0.940000sec

                           user     system      total        real
direct call            0.070000   0.000000   0.070000 (  0.072236)
manual delegation      0.120000   0.000000   0.120000 (  0.122801)
SimpleDelegator        0.330000   0.000000   0.330000 (  0.337177)
DelegateClass          0.300000   0.000000   0.300000 (  0.301587)

@chastell
Copy link

This is why I love benchmark-ips so much – does the right amount of running, shows standard deviation and a comparison. Three subsequent runs on MRI 2.2.0-p0 and i7-3517U:

chastell@devielle:~/coding/delegator_bench* master$ ruby delegator_bench.rb 
2.2.0
Calculating -------------------------------------
         direct call   154.655k i/100ms
   manual delegation   147.608k i/100ms
     SimpleDelegator    83.301k i/100ms
       DelegateClass   100.088k i/100ms
-------------------------------------------------
         direct call      7.624M (± 0.9%) i/s -     38.200M
   manual delegation      5.441M (± 0.8%) i/s -     27.307M
     SimpleDelegator      1.821M (± 0.4%) i/s -      9.163M
       DelegateClass      2.274M (± 1.7%) i/s -     11.410M

Comparison:
         direct call:  7624038.2 i/s
   manual delegation:  5440655.5 i/s - 1.40x slower
       DelegateClass:  2274447.1 i/s - 3.35x slower
     SimpleDelegator:  1821140.0 i/s - 4.19x slower

chastell@devielle:~/coding/delegator_bench* master$ ruby delegator_bench.rb 
2.2.0
Calculating -------------------------------------
         direct call   147.330k i/100ms
   manual delegation   140.938k i/100ms
     SimpleDelegator    89.453k i/100ms
       DelegateClass   101.876k i/100ms
-------------------------------------------------
         direct call      7.770M (± 0.8%) i/s -     38.895M
   manual delegation      5.511M (± 1.0%) i/s -     27.624M
     SimpleDelegator      2.255M (± 0.7%) i/s -     11.361M
       DelegateClass      2.511M (± 0.4%) i/s -     12.633M

Comparison:
         direct call:  7770463.0 i/s
   manual delegation:  5511189.7 i/s - 1.41x slower
       DelegateClass:  2510641.3 i/s - 3.10x slower
     SimpleDelegator:  2255441.7 i/s - 3.45x slower

chastell@devielle:~/coding/delegator_bench* master$ ruby delegator_bench.rb 
2.2.0
Calculating -------------------------------------
         direct call   155.063k i/100ms
   manual delegation   147.376k i/100ms
     SimpleDelegator    82.357k i/100ms
       DelegateClass    99.892k i/100ms
-------------------------------------------------
         direct call      7.648M (± 1.1%) i/s -     38.301M
   manual delegation      5.525M (± 0.9%) i/s -     27.707M
     SimpleDelegator      1.819M (± 0.9%) i/s -      9.142M
       DelegateClass      2.213M (± 0.5%) i/s -     11.088M

Comparison:
         direct call:  7647978.9 i/s
   manual delegation:  5525266.9 i/s - 1.38x slower
       DelegateClass:  2212954.9 i/s - 3.46x slower
     SimpleDelegator:  1818685.7 i/s - 4.21x slower

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment