Created
February 23, 2017 01:56
-
-
Save satoruk/ae1ea4a37830fcbc827464226a04aef7 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
require 'bundler' | |
Bundler.setup | |
require 'benchmark/ips' | |
class ArrayDemo | |
def initialize(data) | |
@data = data | |
end | |
def func_a | |
@data[0] | |
end | |
def func_b | |
@data[1] | |
end | |
def func_c | |
@data[2] | |
end | |
end | |
class ConstArrayDemo | |
INDEX_A=0 | |
INDEX_B=1 | |
INDEX_C=2 | |
def initialize(data) | |
@data = data | |
end | |
def func_a | |
@data[INDEX_A] | |
end | |
def func_b | |
@data[INDEX_B] | |
end | |
def func_c | |
@data[INDEX_C] | |
end | |
end | |
demos = [] | |
demos << {}.tap do |demo| | |
demo[:name] = 'Array Access' | |
index_a = 0 | |
index_b = 1 | |
index_c = 2 | |
data = %w(Apple Banana Chocolate) | |
demo[:func] = lambda do | |
tmp1 = data[index_a] | |
tmp2 = data[index_b] | |
tmp3 = data[index_c] | |
"#{tmp1}_#{tmp2}_#{tmp3}" | |
end | |
end | |
demos << {}.tap do |demo| | |
demo[:name] = ['Hash Access', 'Symbole'] | |
index_a = :a | |
index_b = :b | |
index_c = :c | |
data = { index_a => 'Apple', index_b => 'Banana', index_c => 'Chocolate' } | |
demo[:func] = lambda do | |
tmp1 = data[index_a] | |
tmp2 = data[index_b] | |
tmp3 = data[index_c] | |
"#{tmp1}_#{tmp2}_#{tmp3}" | |
end | |
end | |
demos << {}.tap do |demo| | |
demo[:name] = ['Hash Access', 'String'] | |
index_a = 'a' | |
index_b = 'b' | |
index_c = 'c' | |
data = { index_a => 'Apple', index_b => 'Banana', index_c => 'Chocolate' } | |
demo[:func] = lambda do | |
tmp1 = data[index_a] | |
tmp2 = data[index_b] | |
tmp3 = data[index_c] | |
"#{tmp1}_#{tmp2}_#{tmp3}" | |
end | |
end | |
demos << {}.tap do |demo| | |
demo[:name] = ['New Object Access', 'inside array'] | |
data = %w(Apple Banana Chocolate) | |
demo[:func] = lambda do | |
obj = ArrayDemo.new(data) | |
tmp1 = obj.func_a | |
tmp2 = obj.func_b | |
tmp3 = obj.func_c | |
"#{tmp1}_#{tmp2}_#{tmp3}" | |
end | |
end | |
demos << {}.tap do |demo| | |
demo[:name] = ['Object Access', 'inside array'] | |
data = %w(Apple Banana Chocolate) | |
obj = ArrayDemo.new(data) | |
demo[:func] = lambda do | |
tmp1 = obj.func_a | |
tmp2 = obj.func_b | |
tmp3 = obj.func_c | |
"#{tmp1}_#{tmp2}_#{tmp3}" | |
end | |
end | |
demos << {}.tap do |demo| | |
demo[:name] = ['Object Access', 'inside array with const'] | |
data = %w(Apple Banana Chocolate) | |
obj = ConstArrayDemo.new(data) | |
demo[:func] = lambda do | |
tmp1 = obj.func_a | |
tmp2 = obj.func_b | |
tmp3 = obj.func_c | |
"#{tmp1}_#{tmp2}_#{tmp3}" | |
end | |
end | |
# Comparison: | |
# Array Access: 1560902.4 i/s | |
# (Symbole) Hash Access: 1482838.4 i/s - same-ish: difference falls within error | |
# (inside array with const) Object Access: 1322598.9 i/s - 1.18x slower | |
# (inside array) Object Access: 1310710.3 i/s - 1.19x slower | |
# (String) Hash Access: 1207243.7 i/s - 1.29x slower | |
# (inside array) New Object Access: 993665.3 i/s - 1.57x slower | |
# | |
# ruby 2.2.4p230 (2015-12-16 revision 53155) [x86_64-darwin16] | |
Benchmark.ips do |x| | |
w = demos.map do |v| | |
v[:name] = [v[:name]] unless v[:name].is_a? Array | |
v[:name].join.length | |
end.max | |
demos.each do |v| | |
format = "%#{w + 3}s" | |
format = "(%s) %#{w - v[:name][1].length}s" if v[:name].length > 1 | |
v[:label] = format % v[:name].reverse | |
end | |
demos.each do |demo| | |
x.report(demo[:label]) { demo[:func].call } | |
end | |
x.compare! | |
end | |
puts RUBY_DESCRIPTION |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment