Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: opal/opal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 10cf49cbcf58
Choose a base ref
...
head repository: opal/opal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: e0d02252ac3f
Choose a head ref
  • 2 commits
  • 6 files changed
  • 2 contributors

Commits on Jun 6, 2015

  1. Copy the full SHA
    fac05e9 View commit details
  2. Merge pull request #914 from vais/benchmark-dispatch

    Add Avdi Grimm-inspired dispatch benchmarks
    elia committed Jun 6, 2015
    Copy the full SHA
    e0d0225 View commit details
57 changes: 57 additions & 0 deletions benchmark/bm_dispatch_bind_table.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
class BindTableDispatch
attr_reader :event_log

def initialize
@event_log = []
end

def self.method_added_cheat(method_name)
if method_name.to_s =~ /^handle_(.+)$/
handler_methods[$1.to_sym] = instance_method(method_name)
end
# Cheating here, because Opal does not support method_added hook yet
# Uncomment the super below when it does:
# super
end

def self.handler_methods
@handler_methods ||= {}
end

def call(event)
if (handler_method = self.class.handler_methods[event.name])
handler_method.bind(self).call(event)
end
end

def handle_foo(event)
event_log << event
end

def handle_bar(event)
event_log << event
end

def handle_baz(event)
event_log << event
end
end

klass = BindTableDispatch
event = Struct.new(:name, :source, :args)

# Cheating here, because Opal does not support method_added hook yet
klass.method_added_cheat(:handle_foo)
klass.method_added_cheat(:handle_bar)
klass.method_added_cheat(:handle_baz)

100_000.times do
obj = klass.new
obj.call(e1 = event[:foo])
obj.call(e2 = event[:bar])
obj.call(e3 = event[:baz])
obj.call(event[:buz])
unless obj.event_log == [e1, e2, e3]
raise "#{klass}: #{obj.event_log.inspect}"
end
end
65 changes: 65 additions & 0 deletions benchmark/bm_dispatch_code_gen.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
class CodeGenDispatch
attr_reader :event_log

def initialize
@event_log = []
end

def self.method_added_cheat(method_name)
if method_name.to_s =~ /^handle_(.+)$/
handler_methods << $1
regenerate_dispatch_method
end
# Cheating here, because Opal does not support method_added hook yet
# Uncomment the super below when it does:
# super
end

def self.handler_methods
@handler_methods ||= []
end

def self.regenerate_dispatch_method
dispatch_table = handler_methods.map { |event_name|
"when :#{event_name} then handle_#{event_name}(event)"
}.join("\n")
class_eval %{
def call(event)
case event.name
#{dispatch_table}
end
end
}
end

def handle_foo(event)
event_log << event
end

def handle_bar(event)
event_log << event
end

def handle_baz(event)
event_log << event
end
end

klass = CodeGenDispatch
event = Struct.new(:name, :source, :args)

# Cheating here, because Opal does not support method_added hook yet
klass.method_added_cheat(:handle_foo)
klass.method_added_cheat(:handle_bar)
klass.method_added_cheat(:handle_baz)

100_000.times do
obj = klass.new
obj.call(e1 = event[:foo])
obj.call(e2 = event[:bar])
obj.call(e3 = event[:baz])
obj.call(event[:buz])
unless obj.event_log == [e1, e2, e3]
raise "#{klass}: #{obj.event_log.inspect}"
end
end
64 changes: 64 additions & 0 deletions benchmark/bm_dispatch_code_gen_if.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
class IfCodeGenDispatch
attr_reader :event_log

def initialize
@event_log = []
end

def self.method_added_cheat(method_name)
if method_name.to_s =~ /^handle_(.+)$/
handler_methods << $1
regenerate_dispatch_method
end
# Cheating here, because Opal does not support method_added hook yet
# Uncomment the super below when it does:
# super
end

def self.handler_methods
@handler_methods ||= []
end

def self.regenerate_dispatch_method
dispatch_table = handler_methods.map { |event_name|
"event.name.equal?(:#{event_name}) then handle_#{event_name}(event)"
}.join("\nelsif ")
class_eval %{
def call(event)
if #{dispatch_table}
end
end
}
end

def handle_foo(event)
event_log << event
end

def handle_bar(event)
event_log << event
end

def handle_baz(event)
event_log << event
end
end

klass = IfCodeGenDispatch
event = Struct.new(:name, :source, :args)

# Cheating here, because Opal does not support method_added hook yet
klass.method_added_cheat(:handle_foo)
klass.method_added_cheat(:handle_bar)
klass.method_added_cheat(:handle_baz)

100_000.times do
obj = klass.new
obj.call(e1 = event[:foo])
obj.call(e2 = event[:bar])
obj.call(e3 = event[:baz])
obj.call(event[:buz])
unless obj.event_log == [e1, e2, e3]
raise "#{klass}: #{obj.event_log.inspect}"
end
end
44 changes: 44 additions & 0 deletions benchmark/bm_dispatch_hardcoded.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
class HardcodedDispatch
attr_reader :event_log

def initialize
@event_log = []
end

def call(event)
case event.name
when :foo
handle_foo(event)
when :bar
handle_bar(event)
when :baz
handle_baz(event)
end
end

def handle_foo(event)
event_log << event
end

def handle_bar(event)
event_log << event
end

def handle_baz(event)
event_log << event
end
end

klass = HardcodedDispatch
event = Struct.new(:name, :source, :args)

100_000.times do
obj = klass.new
obj.call(e1 = event[:foo])
obj.call(e2 = event[:bar])
obj.call(e3 = event[:baz])
obj.call(event[:buz])
unless obj.event_log == [e1, e2, e3]
raise "#{klass}: #{obj.event_log.inspect}"
end
end
38 changes: 38 additions & 0 deletions benchmark/bm_dispatch_send.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
class SendDispatch
attr_reader :event_log

def initialize
@event_log = []
end

def call(event)
handler_name = "handle_#{event.name}"
__send__(handler_name, event) if respond_to?(handler_name)
end

def handle_foo(event)
event_log << event
end

def handle_bar(event)
event_log << event
end

def handle_baz(event)
event_log << event
end
end

klass = SendDispatch
event = Struct.new(:name, :source, :args)

100_000.times do
obj = klass.new
obj.call(e1 = event[:foo])
obj.call(e2 = event[:bar])
obj.call(e3 = event[:baz])
obj.call(event[:buz])
unless obj.event_log == [e1, e2, e3]
raise "#{klass}: #{obj.event_log.inspect}"
end
end
57 changes: 57 additions & 0 deletions benchmark/bm_dispatch_send_table.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
class SendTableDispatch
attr_reader :event_log

def initialize
@event_log = []
end

def self.method_added_cheat(method_name)
if method_name.to_s =~ /^handle_(.+)$/
handler_methods[$1.to_sym] = method_name.to_sym
end
# Cheating here, because Opal does not support method_added hook yet
# Uncomment the super below when it does:
# super
end

def self.handler_methods
@handler_methods ||= {}
end

def call(event)
if (handler_method = self.class.handler_methods[event.name])
__send__(handler_method, event)
end
end

def handle_foo(event)
event_log << event
end

def handle_bar(event)
event_log << event
end

def handle_baz(event)
event_log << event
end
end

klass = SendTableDispatch
event = Struct.new(:name, :source, :args)

# Cheating here, because Opal does not support method_added hook yet
klass.method_added_cheat(:handle_foo)
klass.method_added_cheat(:handle_bar)
klass.method_added_cheat(:handle_baz)

100_000.times do
obj = klass.new
obj.call(e1 = event[:foo])
obj.call(e2 = event[:bar])
obj.call(e3 = event[:baz])
obj.call(event[:buz])
unless obj.event_log == [e1, e2, e3]
raise "#{klass}: #{obj.event_log.inspect}"
end
end