Skip to content

Instantly share code, notes, and snippets.

@matsumonkie
Created June 15, 2014 21:21
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 matsumonkie/81aa64724424652b20a8 to your computer and use it in GitHub Desktop.
Save matsumonkie/81aa64724424652b20a8 to your computer and use it in GitHub Desktop.
dci benchmarks
require 'benchmark'
require 'delegate'
#---------------------------------------------------------------
# ruby normal implementation
#---------------------------------------------------------------
module Mover
def accelerate(speed:)
@speed += speed
end
end
class Car
include Mover
attr_reader :speed, :speed_limit
def initialize(speed: 0, speed_limit:)
@speed = speed
@speed_limit = speed_limit
end
end
def include_module
car = Car.new(speed: 0, speed_limit: 100)
car.accelerate(speed: 10)
car.accelerate(speed: 50)
car.accelerate(speed: 50)
end
#---------------------------------------------------------------
# using a decorator
#---------------------------------------------------------------
class Car2
attr_accessor :speed, :speed_limit
def initialize(speed: 0, speed_limit:)
@speed = speed
@speed_limit = speed_limit
end
end
class Mover2 < SimpleDelegator
def initialize(car:)
super(car: car)
end
def accelerate(speed:)
self[:car].speed += speed
end
end
def decorator
car2 = Car2.new(speed: 0, speed_limit: 100)
mover2 = Mover2.new(car: car2)
mover2.accelerate(speed: 10)
mover2.accelerate(speed: 50)
mover2.accelerate(speed: 50)
end
#---------------------------------------------------------------
# extending a module dynamically
#---------------------------------------------------------------
class Car3
attr_reader :speed, :speed_limit
def initialize(speed: 0, speed_limit:)
@speed = speed
@speed_limit = speed_limit
end
end
module Mover3
def accelerate(speed:)
@speed += speed
end
end
class MoveContext
def self.call(movable:, speed:)
self.new(movable).run(speed)
end
def initialize(movable)
@movable = movable
@movable.extend(Mover)
end
def run(speed)
#puts "moving at #{@movable.speed} km/h, trying to accelerate"
if (@movable.speed + speed < @movable.speed_limit)
@movable.accelerate(speed: speed)
#puts "now moving at #{@movable.speed} km/h"
else
#puts "cannot accelerate anymore"
end
end
end
def dci_with_extend
car = Car3.new(speed: 0, speed_limit: 100)
MoveContext::call(movable: car, speed: 10)
MoveContext::call(movable: car, speed: 50)
MoveContext::call(movable: car, speed: 50)
end
#---------------------------------------------------------------
#
#---------------------------------------------------------------
module Role
attr_accessor :role
def method_missing(method_name, *args, &block)
if role && role.public_method_defined?(method_name)
role.instance_method(method_name).bind(self).call(*args, &block)
else
super
end
end
def respond_to_missing?(method_name, include_all=false)
if role && role.public_method_defined?(method_name)
true
else
super
end
end
def play_role(role)
self.role = role
yield(self)
ensure
self.role = nil
end
end
class Car4
include Role
attr_reader :speed, :speed_limit
def initialize(speed: 0, speed_limit:)
@speed = speed
@speed_limit = speed_limit
end
end
module Mover4
def accelerate(speed:)
@speed += speed
end
end
def dci_with_binding
car4 = Car4.new(speed: 0, speed_limit: 100)
car4.play_role(Mover4) do |c|
c.accelerate(speed: 10)
c.accelerate(speed: 50)
c.accelerate(speed: 50)
end
end
Benchmark.bm do |x|
n = 100_000
padding = 16
x.report("%#{padding}s" % 'include_module') {
n.times { include_module() }
}
x.report("%#{padding}s" % 'decorator') {
n.times { decorator() }
}
x.report("%#{padding}s" % 'dci_with_extend') {
n.times { dci_with_extend() }
}
x.report("%#{padding}s" % 'dci_with_binding') {
n.times { dci_with_binding() }
}
end
=begin
user system total real
include_module 0.460000 0.010000 0.470000 ( 0.463059)
decorator 0.760000 0.000000 0.760000 ( 0.767154)
dci_with_extend 1.130000 0.000000 1.130000 ( 1.135473)
dci_with_binding 1.000000 0.000000 1.000000 ( 0.998439)
=end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment