Skip to content

Instantly share code, notes, and snippets.

@tjws052009
Created January 24, 2014 10:55
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tjws052009/8595367 to your computer and use it in GitHub Desktop.
Save tjws052009/8595367 to your computer and use it in GitHub Desktop.
実験でrubyの「普通」な書き方と、関数型っぽい書き方の実行速度を比べてみたくなったので、消費税計算っぽい事をお題にやってみた。
#-*- 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}"
@tjws052009
Copy link
Author

全然まとめられてないんですが、

  1. time tax = 0.000000 0.000000 0.000000 ( 0.000110)
  2. time lambda = 0.000000 0.000000 0.000000 ( 0.000385)
  3. time sum0 = 0.070000 0.000000 0.070000 ( 0.068708)
  4. time sum1 = 0.070000 0.000000 0.070000 ( 0.070950)
  5. time sum2 = 0.070000 0.010000 0.080000 ( 0.074503)
  6. time sum3 = 0.080000 0.000000 0.080000 ( 0.079940)
  7. time sum4 = 0.080000 0.000000 0.080000 ( 0.084216)
  8. time sum5 = 0.220000 0.000000 0.220000 ( 0.214901)
  9. time sum_i = 0.130000 0.000000 0.130000 ( 0.130125)

普通にeach で書くのが一番早かった。そりゃそうか。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment