効率
「ちょっと気になったので、実験してみた。」
わざわざクラスを定義するほどでもないなぁ…と思った時に気軽に Hash を使っているのだが、アクセス速度が気になったので、ちょっと実験してみた。
--- foo.rb #!/usr/bin/env ruby Max = 50000000 class Foo1 attr_accessor :f1 end obj1 = Foo1.new obj2 = {:f1=>nil} puts "[0] utime = #{Process.times.utime}" (1..Max).each {|item| obj1.f1 = item} puts "[1] utime = #{Process.times.utime}" (1..Max).each {|item| obj2[:f1] = item} puts "[2] utime = #{Process.times.utime}" for item in 1..Max do obj1.f1 = item end puts "[3] utime = #{Process.times.utime}" for item in 1..Max do obj2[:f1] = item end puts "[4] utime = #{Process.times.utime}"
1, 3 がアクセサーで 2, 4 が Hash。1,2 がイテレーターで 3,4 が一般的なループ。
実行結果は次の通り。(最後の列はエクセルで追加。)
ラベル | 累積 | 時間 |
---|---|---|
[0] utime = | 0.01 sec | |
[1] utime = | 49.58 sec | 49.57 sec |
[2] utime = | 101.82 sec | 52.24 sec |
[3] utime = | 144.56 sec | 42.74 sec |
[4] utime = | 190.00 sec | 45.44 sec |
これだけの処理時間で数秒の差なので、Ruby ではアクセサーと Hash の間で有意な差はない考えて良さそう。Ruby の内部のことまでは分からないけど、似たような仕組みで管理してそうな気はする。まあ、パフォーマンスを理由にして実装を選択する必要はなさそうだ。
最近、ループはめっきり使わなくなってしまったのだけど、イテレーターよりもループの方が早いのはちょっと残念。