mieki256's diary



2011/10/03(月) [n年前の日記]

#2 [prog] Ruby の case when とメソッドテーブルについて調べたり

Ruby の解説ページをググっていたら、case when は if文に変換されるという話を見かけて、処理時間が気になってきたわけで。テーブルジャンプにしたいけど書き方が分からない。が、ダメ元で某2chで質問してみたら、書き方についてレスがいただけたので、感謝しつつ引き続き調査。

以下のようなスクリプトを書いてベンチマークを取ってみた。
#!/usr/bin/ruby

require "benchmark"

LOOP_MAX = 100000

def func0(x) return x * 3 end
def func1(x) return x * 4 end
def func2(x) return x * 5 end
def func3(x) return x * 6 end
def func4(x) return x * 7 end
def func5(x) return x * 8 end
def func6(x) return x * 9 end
def func7(x) return x * 10 end
def func8(x) return x * 11 end
def func9(x) return x * 12 end
def func10(x) return x * 13 end
def func11(x) return x * 14 end
def func12(x) return x * 15 end
def func13(x) return x * 16 end
def func14(x) return x * 17 end
def func15(x) return x * 18 end

$a = 0
$b = 0

$fixnum = 15

puts Benchmark::CAPTION
puts Benchmark.measure{
    LOOP_MAX.times{ |i|
        # x = i % 16
        x = $fixnum
        r = 0
        case x
        when 0
            r = x * 3
        when 1
            r = x * 4
        when 2
            r = x * 5
        when 3
            r = x * 6
        when 4
            r = x * 7
        when 5
            r = x * 8
        when 6
            r = x * 9
        when 7
            r = x * 10
        when 8
            r = x * 11
        when 9
            r = x * 12
        when 10
            r = x * 13
        when 11
            r = x * 14
        when 12
            r = x * 15
        when 13
            r = x * 16
        when 14
            r = x * 17
        when 15
            r = x * 18
        end
        $a += r
    }
}

puts Benchmark.measure{
    funclist = [
    :func0,
    :func1,
    :func2,
    :func3,
    :func4,
    :func5,
    :func6,
    :func7,
    :func8,
    :func9,
    :func10,
    :func11,
    :func12,
    :func13,
    :func14,
    :func15,
    ]
    
    LOOP_MAX.times{ |i|
        # x = i % 16
        x = $fixnum
        r = send( funclist[x], x )
        $b += r
    }
}

puts "a=#{$a}"
puts "b=#{$b}"

Core2Duo E8400 3.0GHz + Windows7 Pro 64bit + ActiveScriptRuby 1.8.7 p330 での実行結果は以下の通り。
      user     system      total        real
  0.374000   0.000000   0.374000 (  0.380038)
  0.140000   0.000000   0.140000 (  0.146014)
a=27000000
b=27000000
色々試してみたが、以下のような感じの結果に。 もちろん、その部分がボトルネックになっているなら、の話だけど。たまにしか処理が来ないならどうでもいい。

が、某2chで、「1.9はテーブルジャンプに置き換えてくれるはずだ」という話が。

ActiveScriptRuby 1.9.2 p290 で試してみたところ、以下の結果に。
      user     system      total        real
  0.031000   0.000000   0.031000 (  0.030003)
  0.031000   0.000000   0.031000 (  0.027003)
a=27000000
b=27000000
ほとんど同じ処理時間。しかも、1.9.2 のほうが、1.8.7 より 5〜12倍速い。

ここまで速くなるとは知らなかった。Ruby 1.9 の最適化?は素晴らしいなと。

ということで結論。書き方次第で速くなるかも、などとグダグダ悩むぐらいなら、どうにかして Ruby 1.9 で動かせないかを悩んだほうがはるかに効率がいい。

でも、exerb って Ruby 1.9 には対応してなかったような記憶が。

以前、手持ちのネットブック機(Atom CPU)上で、exerb と ocra でexe化したスクリプトを動かしたら、exerb版に比べてocra版は、起動するまでの時間が数倍かかってゲンナリした記憶があり。なので、最終的に exe化する可能性があるなら、極力 Ruby 1.8.x でやるべきかな、と思っていたわけで。どうしたもんか。

まあ、そのネットブック上で DXRuby のスクリプトを動かすと、メイン機上では軽々と60FPS出ていたスクリプトが、6〜10FPS程度になったりするわけで。 *1 そういう環境は無視してしまっていいのかもしれない。
*1: おそらく、DirectX にはほとんど対応できていないオンボードビデオなんだと思う。

以上です。

過去ログ表示

Prev - 2011/10 - Next
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project