サイログ。

~雑多な記事置き場~

やる夫がFiberパフォーマンス測定してみたそうです その1

(はてなの投稿制限食らって途中までしか公開できません。あとは後日)

       ____
      /      \
     /  ─    ─\    最近、Ruby1.9.1にFiberが追加されたけど、
   /    (●)  (●) \    「遅い」「遅い」ってよく言われるお
   |       (__人__)    | ________
    \      ` ⌒´   ,/ | |          |
   ノ           \ | |          |
 /´                 | |          |
|    l                | |          |
ヽ    -一ー_~、⌒)^),-、   | |_________|
 ヽ ____,ノγ⌒ヽ)ニニ- ̄   | |  |
     ____
   /      \
  /  ─    ─\      でも、それは本当なのだろうか・・・。
/    (●)  (●) \    客観的なデータが手元にないので、
|       (__人__)    |  判断に困るお。
/     ∩ノ ⊃  /
(  \ / _ノ |  |
.\ “  /__|  |
  \ /___ /
       ____ 
     /⌒  ⌒\ 
   /( ●)  (●)\ 
  /::::::⌒(__人__)⌒::::: \   だから早速パフォーマンス測定してみるお!
  |     |r┬-|     | 
  \      `ー'´     /
                   では早速プログラムを作るお
         ____      ベンチマークのやり方がわからないので
      /      \    <s>「けいおん!」の単行本</s>
     /  ─    ─\    るりまを片手に書くお
   /    (●)  (●) \  
   |       (__人__)    | ________
    \      ` ⌒´   ,/ | |          |
   ノ           \ | |          |
 /´                 | |          |
|    l                | |          |
ヽ    -一ー_~、⌒)^),-、   | |_________|
 ヽ ____,ノγ⌒ヽ)ニニ- ̄   | |  |
         ____    
      /      \    ・・・お、Benchmarkモジュールか、
     /  ─    ─\    これで時間測定やるわけだな。
   /    (●)  (●) \  めんどくさいのでコピペするお
   |       (__人__)    | ________
    \      ` ⌒´   ,/ | |          |
   ノ           \ | |          |
 /´                 | |          |
|    l                | |          |
ヽ    -一ー_~、⌒)^),-、   | |_________|
 ヽ ____,ノγ⌒ヽ)ニニ- ̄   | |  |
require 'benchmark'

size  = 100
outer = 3
inner = 100000

Benchmark.benchmark (" "*11 + Benchmark::CAPTION) do |bm|
  org = bm.report("original_loop:") do
    array = Array.new(size){|i| i}
    outer.times do
      sum = 0
      idx = 0
      inner.times do
        sum += array[idx]
        idx = (idx + 1) % array.length
      end
    end
  end
end

アルゴリズム解説はムギから。

                           7⌒ ー-
                           /  /| ,′  ヽ `ヽ
                        / / /-‐ト、{  卜、 ‘,
.      | ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|/´ ̄「 ∧ L 」  }
.      | 配列の要素を順に参照   l,ィ扞トl/  ヽト、|     }
.      | 各要素の総和をも求める  l ヒ'シ   .ミ、 | ハ   /
        |                   .      |''   .   {t.r}j |/ | /
       | 配列の終端まで来たら、  | 、   `,,^ } |'
      | 先頭に戻って続けて    |、  `    'フ   }{
     ,.⊥、                {.n`! ‐--‐,1|T   八
     }ニY ループの回数は            f,二Y´  ̄ト|」」_  /{  ヽ
    rウT′ 外側が3回          {_rこ)  ノ ノ  ,ハ 、
.       ヽ| 内側が10万回の      |   }Y´/   / | ヽ }
      「| 計30万回             l r'{フ/   /   |  ∨
.       !|                    |ノ ,ハ{  /     ハ
.       l|        ♪ギタリスト募集♪.l/゚。∨/ /  /} }   }
.      l|                   |    Y´   / ノノ  ,ハ
       |____________l      |    '}/  /
       丶--‐  ´    /      ,|       |   /-‐     }
                          C八        ∧       /
               {         \    イ} }    /

user system total real
original_loop: 0.390000 0.000000 0.390000 ( 0.390561)

     ____
   /      \
  /  ─    ─\      ふむ、なかなか・・・。
/    (●)  (●) \    なかなかいい成績だお。
|       (__人__)    |   
/     ∩ノ ⊃  /     
(  \ / _ノ |  |
.\ “  /__|  |
  \ /___ /

ちなみに、評価環境はPentimuM 1.2GHzのLet'sNOTEで、
WindowsXpSP3+Ruby1.9.1-p243で評価してるお。

         ____
      /      \    では次に、中でFiberが使われているという
     /  ─    ─\    Enumerator使ってみるお。
   /    (●)  (●) \  アルゴリズムを同じにして・・・と。  
   |       (__人__)    | ________
    \      ` ⌒´   ,/ | |          |
   ノ           \ | |          |
 /´                 | |          |
|    l                | |          |
ヽ    -一ー_~、⌒)^),-、   | |_________|
 ヽ ____,ノγ⌒ヽ)ニニ- ̄   | |  |
require 'benchmark'

size  = 100
outer = 3
inner = 100000

Benchmark.benchmark (" "*11 + Benchmark::CAPTION) do |bm|
  (略)

  enm = bm.report("enumerator:   ") do
    array = Array.new(size){|i| i}
    outer.times do
      sum = 0
      idx = array.cycle
      inner.times do
        sum += idx.next
      end
    end
  end
end

user system total real
original_loop: 0.390000 0.000000 0.390000 ( 0.390562)
enumerator: 2.644000 0.000000 2.644000 ( 2.703888)

     ___ 
    /⌒  ⌒\         ━━┓┃┃ 
   /(  ̄)  (_)\         ┃   ━━━━━━━━ 
 /::::::⌒(__人__)⌒:::: \         ┃               ┃┃┃ 
|    ゝ'゚     ≦ 三 ゚。 ゚                       ┛ 
\   。≧       三 ==-      
゙ヽ, ,__    ,. -ー"ヽヽ 
     ____ 
   /      \ ( ;;;;( 
  /  _ノ  ヽ__\) ;;;;)    
/    (─)  (─ /;;/  えらい速度落ちてるじゃねえか・・・。 
|       (__人__) l;;,´ これはFiberのせいなのか・・・。
/      ∩ ノ)━・'/     パフォーマンス命のデータベース
(  \ / _ノ´.|  |     アプリ作れるんだろうか・・・。
.\  "  /__|  |      使いこなせるかお・・・。
  \ /___    
  / ̄ ̄\ 
/   _ノ  \ 
|    ( ●)(●)
|     (__人__)   まあ、とりあえず、Enumeratorの中に入ってる 
|     ` ⌒´ノ   Fiber単体でのパフォーマンス測定するべきだろ・・・
|         }   常識的に考えて・・・ 
ヽ        } 
 ヽ     ノ        \ 
 /    く  \        \ 
 |     \   \         \ 
 |    |ヽ、二⌒)、          \
         ____ 
+        ./ /  \\ 
       / (●)  (●)\ 
     /   ⌒ノ(、_, )ヽ⌒  \    そうだお! ここは原因が
     |      `-=ニ=-      |   Fiberかどうか
     \      `ー'´      / +  切り分けしなきゃいけないんだお!
     /     ∩ノ ⊃  /      Fiberでスクリプト作ってみて、
     (  \ / _ノ |  | そこから差分を取ればいいんだお!
     .\ “  /__|  | 
      . \ /___ / 

(続く(えー))