Created
January 24, 2014 10:55
-
-
Save tjws052009/8595367 to your computer and use it in GitHub Desktop.
実験でrubyの「普通」な書き方と、関数型っぽい書き方の実行速度を比べてみたくなったので、消費税計算っぽい事をお題にやってみた。
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
#-*- coding:utf-8 -*- | |
# | |
# Ruby skeleton file | |
# | |
require 'benchmark' | |
require 'ruby-prof' | |
itrs = 500 | |
price = 101 | |
# list = [1000, 2000, 696, 389, 392] | |
list = [] | |
itrs.times do | |
list << rand(100) | |
end | |
# 単純に税込みにするための関数を追加 | |
class Numeric | |
def tax | |
(self * Base::TAX_RATE).floor | |
end | |
def tax_lambda | |
-> i{(self * Base::TAX_RATE).floor} | |
end | |
end | |
class Base | |
TAX_RATE = 1.05 | |
def self.tax(price) | |
(price * TAX_RATE).floor | |
end | |
def self.sum0(list) | |
total = 0 | |
list.each {|l| total += self.tax(l)} | |
return total | |
end | |
def self.sum0_n(list) | |
total = 0 | |
list.each {|l| total += l.tax} | |
return total | |
end | |
def self.sum_i(list) | |
return 0 if list.empty? | |
list.first.tax + Base.sum_i(list.drop 1) | |
end | |
def self.fact(n) | |
return 1 if n == 0 | |
n * self.fact(n - 1) | |
end | |
def self.sum1(list) | |
list.inject(0) {|l, m| l + self.tax(m)} | |
end | |
def self.sum2(list) | |
list.map(&-> i{self.tax(i)}).reduce(:+) | |
end | |
def self.sum3(list) | |
list.map{|i| self.tax(i)}.reduce(:+) | |
end | |
def self.sum4(list) | |
list.map{|i| self.tax(i)}.inject(:+) | |
end | |
def self.sum5(list) | |
list.lazy.select{|a| a < 50}.map{|i| self.tax(i)}.to_a.reduce(:+) | |
end | |
def self.sum6(list) | |
list.lazy.map{|i| self.tax(i)}.to_a.reduce(:+) | |
end | |
def self.time | |
st = Time.now | |
yield | |
tt = Time.now - st | |
end | |
end | |
puts "Base.fact(6) = #{Base.fact(6)}" | |
puts "Base.sum_i(list) = #{Base.sum_i(list)}" | |
puts "1) Base.tax(price) = #{Base.tax(price)}" | |
puts "2) Base.sum0(list) = #{Base.sum0(list)}" | |
puts "3) Base.sum1(list) = #{Base.sum1(list)}" | |
puts "4) Base.sum2(list) = #{Base.sum2(list)}" | |
puts "5) Base.sum3(list) = #{Base.sum3(list)}" | |
puts "6) Base.sum4(list) = #{Base.sum4(list)}" | |
puts "7) Base.sum5(list) = #{Base.sum5(list)}" | |
# res0 = Base.time do | |
res0 = Benchmark.measure do | |
itrs.times do | |
100.tax | |
end | |
end | |
res1 = Benchmark.measure do | |
itrs.times do | |
100.tax_lambda | |
end | |
end | |
res2 = Benchmark.measure do | |
itrs.times do | |
Base.sum0(list) | |
end | |
end | |
res3 = Benchmark.measure do | |
itrs.times do | |
Base.sum1(list) | |
end | |
end | |
res4 = Benchmark.measure do | |
itrs.times do | |
Base.sum2(list) | |
end | |
end | |
res5 = Benchmark.measure do | |
itrs.times do | |
Base.sum3(list) | |
end | |
end | |
res6 = Benchmark.measure do | |
itrs.times do | |
Base.sum4(list) | |
end | |
end | |
res7 = Benchmark.measure do | |
itrs.times do | |
Base.sum5(list) | |
end | |
end | |
res8 = Benchmark.measure do | |
itrs.times do | |
Base.sum_i(list) | |
end | |
end | |
#============================== | |
result = RubyProf.profile do | |
itrs.times do | |
Base.sum5(list) | |
end | |
end | |
puts 'res1' | |
# Print a flat profile to text | |
printer = RubyProf::FlatPrinter.new(result) | |
printer.print(STDOUT) | |
#============================== | |
result2 = RubyProf.profile do | |
itrs.times do | |
Base.sum6(list) | |
end | |
end | |
puts 'res2' | |
# Print a flat profile to text | |
printer = RubyProf::FlatPrinter.new(result2) | |
printer.print(STDOUT) | |
#============================== | |
result3 = RubyProf.profile do | |
itrs.times do | |
Base.sum0(list) | |
end | |
end | |
puts 'res3' | |
# Print a flat profile to text | |
printer = RubyProf::FlatPrinter.new(result) | |
printer.print(STDOUT) | |
#============================== | |
result4 = RubyProf.profile do | |
itrs.times do | |
Base.sum_i(list) | |
end | |
end | |
puts 'res4' | |
# Print a flat profile to text | |
printer = RubyProf::FlatPrinter.new(result2) | |
printer.print(STDOUT) | |
puts "1) time tax = #{res0}" | |
puts "2) time lambda = #{res1}" | |
puts "3) time sum0 = #{res2}" | |
puts "4) time sum1 = #{res3}" | |
puts "5) time sum2 = #{res4}" | |
puts "6) time sum3 = #{res5}" | |
puts "7) time sum4 = #{res6}" | |
puts "8) time sum5 = #{res7}" | |
puts "9) time sum_i = #{res8}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
全然まとめられてないんですが、
普通にeach で書くのが一番早かった。そりゃそうか。