速度測定2

昨日の続き。

__send__

せっかくなので実験

#!/usr/bin/env ruby

require 'benchmark'

n = 500000
Benchmark.bm do |x|
  ary = Array.new(n)

  x.report{
    def hoge
      "hoge"
    end

    n.times do
      hoge
    end
  }

  x.report{
    def hoge
      "hoge"
    end

    n.times do
      __send__(:hoge)
    end
  }

  x.report{
    hoge = lambda{
      "hoge"
  }

    n.times do
      hoge.call
    end
  }
end
$ ./hoge.rb 
      user     system      total        real
  1.150000   0.270000   1.420000 (  1.471690)
  1.360000   0.260000   1.620000 (  1.649277)
  2.320000   0.350000   2.670000 (  2.685540)


メソッドを通常の方法で呼ぶのが一番早い。
次に__send__。このあたりは誤差の範囲。
予想外にlambdaが一番遅い。
しかも上2つと比べて明らかに違う。


lambdaは一時意味が分からなくて、Ruby->Scheme->Rubyの順で勉強したので、
微妙にSchemeとイメージが違う。
RubyのlambdaはSchemeと違いlambdaの外の変数がそのまま使用できたりするし...
なんか動作だけ見ていると、__send__の方がSchemeのlambdaにイメージが近い。
まあ実際に__send__の動作

Array#each

使わないのにeachで値を取る/取らない

#!/usr/bin/env ruby

require 'benchmark'

n = 500000
Benchmark.bm do |x|
  ary = Array.new(n)

  x.report{
    ary.each do |obj|
      Time.now
    end
  }

  x.report{
    ary.each do
      Time.now
    end
  }
end
$ ./hoge.rb
      user     system      total        real
  1.880000   0.570000   2.450000 (  2.498371)
  1.480000   0.480000   1.960000 (  1.979431)


多少だがやはり影響がある。
無駄なことはするなと。

Arrayに値を設定

既に作ったArrayに値を設定するのと、
空のArrayに値を設定していってArrayを大きくしていくのと。

#!/usr/bin/env ruby

require 'benchmark'

n = 500000
Benchmark.bm do |x|
  ary = Array.new(n)

  x.report{
    n.times do |i|
      ary[i] = 100
    end
  }

  x.report{
    a = []
    n.times do |i|
      a << 100
    end
  }
end
$ ./hoge.rb 
      user     system      total        real
  0.860000   0.250000   1.110000 (  1.147008)
  0.910000   0.240000   1.150000 (  1.151646)


ほとんど差がない。
後者の方が遅くなるかと思ったんだけど。