Created
December 4, 2019 19:01
-
-
Save eviltrout/b41224d28a406579fa28ad0ef6b180e0 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
# frozen_string_literal: true | |
require 'benchmark/ips' | |
class Key | |
def a? | |
true | |
end | |
def b? | |
false | |
end | |
def c? | |
true | |
end | |
def d? | |
false | |
end | |
def e? | |
true | |
end | |
end | |
def parts | |
@parts ||= { | |
a: ->(x) { x.a? }, | |
b: ->(x) { x.b? }, | |
c: ->(x) { x.c? }, | |
d: ->(x) { x.d? }, | |
e: ->(x) { x.e? } | |
} | |
end | |
def parts_methods | |
@parts_methods ||= { | |
a: 'a?', | |
b: 'b?', | |
c: 'c?', | |
d: 'd?', | |
e: 'e?' | |
} | |
end | |
def each_key(key) | |
str = +'' | |
parts.each do |k, v| | |
str << "#{k}=#{v.call(key)}" | |
end | |
str | |
end | |
def compile_method | |
method = +"def __compiled_key(key)\n \"" | |
parts_methods.each do |k, v| | |
method << "#{k}=#\{key.#{v}}" | |
end | |
method << "\"\nend" | |
eval(method) | |
end | |
def string_key(key) | |
"a=#{key.a?}b=#{key.b?}c=#{key.c?}d=#{key.d?}e=#{key.e?}" | |
end | |
compile_method | |
key = Key.new | |
orig = each_key(key) | |
if orig != string_key(key) || orig != __compiled_key(key) | |
raise 'broken implementation' | |
end | |
Benchmark.ips do |x| | |
x.report('string') do |times| | |
i = 0 | |
while i < times | |
string_key(key) | |
i += 1 | |
end | |
end | |
x.report('each') do |times| | |
i = 0 | |
while i < times | |
each_key(key) | |
i += 1 | |
end | |
end | |
x.report('compiled') do |times| | |
i = 0 | |
while i < times | |
__compiled_key(key) | |
i += 1 | |
end | |
end | |
x.compare! | |
end | |
# Warming up -------------------------------------- | |
# string 134.918k i/100ms | |
# each 52.150k i/100ms | |
# compiled 136.464k i/100ms | |
# Calculating ------------------------------------- | |
# string 1.639M (± 2.2%) i/s - 8.230M in 5.022614s | |
# each 562.231k (± 2.0%) i/s - 2.816M in 5.010807s | |
# compiled 1.686M (± 2.0%) i/s - 8.461M in 5.019652s | |
# | |
# Comparison: | |
# compiled: 1686221.1 i/s | |
# string: 1639373.0 i/s - same-ish: difference falls within error | |
# each: 562231.5 i/s - 3.00x slower | |
This file contains hidden or 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
# frozen_string_literal: true | |
require 'benchmark/ips' | |
class Key | |
def a? | |
true | |
end | |
def b? | |
false | |
end | |
def c? | |
true | |
end | |
def d? | |
false | |
end | |
def e? | |
true | |
end | |
end | |
def parts | |
@parts ||= { | |
a: ->(x) { x.a? }, | |
b: ->(x) { x.b? }, | |
c: ->(x) { x.c? }, | |
d: ->(x) { x.d? }, | |
e: ->(x) { x.e? } | |
} | |
end | |
def parts_methods | |
@parts_methods ||= { | |
a: 'a?', | |
b: 'b?', | |
c: 'c?', | |
d: 'd?', | |
e: 'e?' | |
} | |
end | |
def each_key(key) | |
str = +'' | |
parts.each do |k, v| | |
str << "#{k}=#{v.call(key)}" | |
end | |
str | |
end | |
def compile_method | |
method = +"def __compiled_key(key)\n \"" | |
parts_methods.each do |k, v| | |
method << "#{k}=#\{key.#{v}}" | |
end | |
method << "\"\nend" | |
eval(method) | |
end | |
def string_key(key) | |
"a=#{key.a?}b=#{key.b?}c=#{key.c?}d=#{key.d?}e=#{key.e?}" | |
end | |
compile_method | |
key = Key.new | |
orig = each_key(key) | |
if orig != string_key(key) || orig != __compiled_key(key) | |
raise 'broken implementation' | |
end | |
Benchmark.ips do |x| | |
x.report('string') do |times| | |
i = 0 | |
while i < times | |
string_key(key) | |
i += 1 | |
end | |
end | |
x.report('each') do |times| | |
i = 0 | |
while i < times | |
each_key(key) | |
i += 1 | |
end | |
end | |
x.report('compiled') do |times| | |
i = 0 | |
while i < times | |
__compiled_key(key) | |
i += 1 | |
end | |
end | |
x.compare! | |
end | |
# Warming up -------------------------------------- | |
# string 134.918k i/100ms | |
# each 52.150k i/100ms | |
# compiled 136.464k i/100ms | |
# Calculating ------------------------------------- | |
# string 1.639M (± 2.2%) i/s - 8.230M in 5.022614s | |
# each 562.231k (± 2.0%) i/s - 2.816M in 5.010807s | |
# compiled 1.686M (± 2.0%) i/s - 8.461M in 5.019652s | |
# | |
# Comparison: | |
# compiled: 1686221.1 i/s | |
# string: 1639373.0 i/s - same-ish: difference falls within error | |
# each: 562231.5 i/s - 3.00x slower | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment