Skip to content

Instantly share code, notes, and snippets.

@satoruk
Created February 23, 2017 01:56
Show Gist options
  • Save satoruk/ae1ea4a37830fcbc827464226a04aef7 to your computer and use it in GitHub Desktop.
Save satoruk/ae1ea4a37830fcbc827464226a04aef7 to your computer and use it in GitHub Desktop.
多次元配列のアクセスのコードをパフォーマンスを成るべく維持しつつ読み易くしたい
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