サイログ。

~雑多な記事置き場~

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

(前回の続き)

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

  fib = bm.report("fiber:        ") do
    outer.times do
      fiber = Fiber.new do
        array = Array.new(size){|i| i}
        idx = 0
        ret = true
        while ret
          ret = Fiber.yield array[idx]
          idx = (idx + 1) % array.length
        end
      end

      sum = 0
      inner.times do
        sum += fiber.resume(true)
      end
      fiber.resume(nil)
    end
  end
end
       ______ 
      /  \    /\
    /  し (>)  (<)\
    | ∪    (__人__)  J | ________ 
     \  u   `⌒´   / | |          |
    ノ           \ | |          |
         ____ 
      /  \    ─\   チラッ 
    /  し (>)  (●)\ 
    | ∪    (__人__)  J | ________ 
     \  u   `⌒´   / | |          |
    ノ           \ | |          |

user system total real
original_loop: 0.410000 0.000000 0.410000 ( 0.410591)
enumerator: 2.644000 0.000000 2.644000 ( 2.643801)
fiber: 7.611000 0.000000 7.611000 ( 7.620959)

         ____ 
      /::::::─三三─\ 
    /:::::::: ( ○)三(○)\    
    |::::::::::::::::::::(__人__)::::  | ________ 
     \:::::::::   |r┬-|   ,/ .| |          |
    ノ::::::::::::  `ー'´   \ .| |          |

        ノ L____
       ⌒ \ / \   いくらなんでもこれはひどすぎるお!
      / (○) (○)\ なんで中身のFiber単体の方が
     /    (__人__)   \ 時間掛かってるのかお!
     |       |::::::|     |   実はFiber使ってませんでした
     \       l;;;;;;l    /l!| ! とかそういうことかお!
     /     `ー'    \ |i
   /          ヽ !l ヽi
   (   丶- 、       しE |そ  ドンッ!!
    `ー、_ノ       ?堯?l、E ノ <
               レY^V^ヽl


      / ̄ ̄\ まぁ落ち着け 
    /   _ノ  \ 
    | u   ( ●)(●)   ____ もういい加減切れたお! 
     |     (__人__)  /:::::::::  u\ 
     |     ` ⌒´ノ/ノ└ \,三_ノ\    ,∩__ 
     |        /::::::⌒( ●)三(●)\ fつuu 
      ヽ       |:::::::::::::::::⌒(__人__)⌒ |  |   | 
      ヽ      \::::::::::   ` ⌒´   ,/ _ |   | 
    /  ̄\   /⌒ .ヽ          i    丿 
    |  ヽ、 \/   /(⌒)       ξ) ̄ ̄´ 
        \ ./   / /         | 
        ノ L____
       ⌒ \ / \   これは陰謀だお!
      / (○) (○)\ 
     /    (__人__)   \ あまりFiber使わせないようにと企む
     |       |::::::|     |   T京大学のS田さんの陰謀だお!
     \       l;;;;;;l    /l!| ! 
     /     `ー'    \ |i
   /          ヽ !l ヽi
   (   丶- 、       しE |そ  ドンッ!!
    `ー、_ノ       ?堯?l、E ノ <
               レY^V^ヽl

      .-´    ``ヽ 妄想めいた捏造スンナ!!!!! 
     /  ヽー     `ヽ
    / ノ    (O )ノ ̄ ̄`ヽ、―ニ  
   / (●) __)⌒/ ´`ヽ _  三,:三ー三,:
   | ::⌒(__ノ/  ノヽ--/ ̄ ,    `   ` ̄ ̄ ̄
  。ヽ 。   )(  }.  ...|  /!    
     ヽo (__ン  }、ー‐し'ゝL _  
    人  ー   jr--‐‐'´}    ;ーー------
   /        ヾ---‐'ーr‐'"==
               | 

(本当は例の「ジャキーン!」を使いたかったけど、幅が狭すぎて強烈に
開業してしまうので断念)

   / ̄ ̄\
 /   _ノ  \
 |    ( ●)(●) 素直にコミケ上京したいって言え
  |     (__人__)
  |     ` ⌒´ノ
   |         }  ミ        ピコッ
   ヽ        } ミ  /\  ,☆____
   ヽ     ノ    \  \ /     \ というわけで、8月半ばに
   /    く  \.  /\/ ─    ─ \ 東K大学へ抗議に行くので
   |     `ー一⌒)  /   (●)  (●)  \アキバ行く旅費ください
    |    i´ ̄ ̄ ̄ \ |      (__人__)     |
               \_   ` ⌒´    /
                /          \

(プレイヤー発言)誤解を生みそうなので補足。
(参考)http://www.atmarkit.co.jp/news/200712/25/ruby.html
リンク先で東京大学の笹田さんは、「FiberはGeneratorを実装するために作ったので、
Fiber自体は(Ruby1.9の目玉として)あまり気にしなくていい」と発言している
また、RubyKaigi2007でFiberの紹介をされていたのも笹田さん

   / ̄ ̄\ 
 /   _ノ  \ 
 |    ( ●)(●)
. |     (__人__)   まあ、さらに原因を掘り下げて行こうな。 
  |     ` ⌒´ノ   Fiberの生成に時間が掛かりすぎるってこと無いか?
.  |         }   常識的に考えて・・・ 
.  ヽ        } 
   ヽ     ノ        \ 
   /    く  \        \ 
   |     \   \         \ 
    |    |ヽ、二⌒)、          \

          ____
       / \  /\  キリッ
.     / (ー)  (ー)\   おーし、では、外側のループを1回、
    /   ⌒(__人__)⌒ \  内側のループを30万回にして試してみるお。
    |      |r┬-|    |
     \     `ー'´   /
    ノ            \
  /´               ヽ
 |    l              \
 ヽ    -一''''''"~~``'ー--、   -一'''''''ー-、.
  ヽ ____(⌒)(⌒)⌒) )  (⌒_(⌒)⌒)⌒))
|Benchmark.benchmark (" "*11 + Benchmark::CAPTION) do |bm|
  (略)

  fib = bm.report("fiber2:       ") do
    1.times do
      fiber = Fiber.new do
        array = Array.new(size){|i| i}
        idx = 0
        ret = true
        while ret
          ret = Fiber.yield array[idx]
          idx = (idx + 1) % array.length
        end
      end

      sum = 0
      300000.times do
        sum += fiber.resume(true)
      end
      fiber.resume(nil)
    end
  end
end

user system total real
fiber: 7.591000 0.000000 7.591000 ( 7.600930)
fiber2: 7.601000 0.000000 7.601000 ( 7.600930)

          ____ 
        /_ノ  ヽ、_\ 
 ミ ミ ミ  o゚((●)) ((●))゚o      ミ ミ ミ 
/⌒)⌒)⌒. ::::::⌒(__人__)⌒:::\   /⌒)⌒)⌒) 
| / / /     |r┬-|    | (⌒)/ / / //  だっておwwwwwww 
| :::::::::::(⌒)    | |  |   /  ゝ  :::::::::::/ 全然変わってないおw
|     ノ     | |  |   \  /  )  /     wwwwwww
ヽ    /     `ー'´      ヽ /    /     バ 
 |    |   l||l 从人 l||l      l||l 从人 l||l  バ   ン 
 ヽ    -一''''''"~~``'ー--、   -一'''''''ー-、    ン 
  ヽ ____(⌒)(⌒)⌒) )  (⌒_(⌒)⌒)⌒))

        / ̄ ̄\    
      /    u  \      .____ 
      |::::::      u |   ./      \   
     . |:::::::::::     |  / ⌒   ⌒  \ いくらなんでもあり得んお。
       |:::::::::::u:    |/  (●) (●)   \  そこまで生成に時間が
     .  |::::::::::::::  u  } |    (__人__)     |  掛かってたら
     .  ヽ::::::::::::::    } \   ` ⌒´     _/      とっくに話題に
        ヽ::::::::::  ノ   |           \         なってるお。
        /:::::::::::: く    | |         |  | 
-―――――|:::::::::::::::: \-―┴┴―――――┴┴――   
         |:::::::::::::::|ヽ、二⌒)        ____ 

     ____
   /      \
  /  ─    ─\   普通に考えれば、まずはresumeとyieldだお。
/    (●)  (●) \ なので、Fiberの中でループさせてみるお。
|       (__人__)    |
/     ∩ノ ⊃  /
(  \ / _ノ |  |
.\ “  /__|  |
  \ /___ /
Benchmark.benchmark (" "*11 + Benchmark::CAPTION) do |bm|
  (略)

  fib = bm.report("fiber3:       ") do
    fiber = Fiber.new do |max|
      array = Array.new(size){|i| i}
      idx = 0
      while max
        sum = 0
        max.times do
          sum += array[idx]
          idx = (idx + 1) % array.length
        end
        max = Fiber.yield sum
      end
    end
    outer.times do
      sum = fiber.resume(inner)
    end
    fiber.resume(nil)
  end
end

user system total real
fiber: 7.641000 0.000000 7.641000 ( 7.651001)
fiber3: 0.360000 0.000000 0.360000 ( 0.360519)

    _|\∧∧∧MMMM∧∧∧/|_
    >                  <
  /\  ──┐| | \     ヽ|  |ヽ  ム ヒ | |
  /  \    /      /  | ̄| ̄ 月 ヒ | |
      \ _ノ    _/   / | ノ \ ノ L_い o o
    `――――――○――――――’

゚ | ・  | .+o   ____* o。 |。|   *。 | 
゚ |i    | +   /_ノ ' ヽ_\   | |!    |     ついにやったお!
o。!    |! ゚o /(≡)   (≡)\   | * ゚ |     パフォーマンス
  。*゚  l ・/::::::⌒(__人__)⌒:::::\ |o  ゚。・    大向上だお!
 *o゚ |! |     |r┬-|     |  + *|         これで、ムギュと
| ・    o \      `ー'´     / *゚・ +||    キャッキャウフフだお!
 |o   |・゚  >         |  *。*   |    
* ゚  l|  /           |    | +| 
 |l + ゚o  /           | *゚・ ||  ・ |o 
 o○ |   | 丶    ヽ  /  | *o|  *。 
・| + ゚ o /| /     | /   |  O *。| 
 O。 | ( ∪  / ̄\∪  ノ。* 。   | 
 o+ |!* \  /     |  ノ   |  *o| 
 |・   | ゚・  )ノ     \ | o○ |! 

゚ | ・  | .+o   ____* o。 |。|   *。 | 
゚ |i    | +   /_ノ ' ヽ_\   | |!    |     
o。!    |! ゚o /(≡)   (≡)\   | * ゚ |     ・・・・・。
  。*゚  l ・/::::::⌒(__人__)⌒:::::\ |o  ゚。・    
 *o゚ |! |     |r┬-|     |  + *| 
| ・    o \      `ー'´     / *゚・ +||    
 |o   |・゚  >         |  *。*   |    
* ゚  l|  /           |    | +| 
 |l + ゚o  /           | *゚・ ||  ・ |o 
 o○ |   | 丶    ヽ  /  | *o|  *。 
・| + ゚ o /| /     | /   |  O *。| 
 O。 | ( ∪  / ̄\∪  ノ。* 。   | 
 o+ |!* \  /     |  ノ   |  *o| 
 |・   | ゚・  )ノ     \ | o○ |! 
             ____
           /      \
          / ─    ─ \
        /   (●)  (●)  \
        |      (__人__)     |   いやいやいや。
         \     ` ⌒´    ,/   結局これ、コンテキスト切り替えの
 r、     r、/          ヘ    メリットが無いから。
 ヽヾ 三 |:l1             ヽ
  \>ヽ/ |` }            | |    普通のメソッド呼び出しと
   ヘ lノ `'ソ             | |    変わってないから。
    /´  /             |. |
    \. ィ                |  |
        |                |  |

   / ̄ ̄\
 /   _ノ  \
 |   ( ●)(●)  <おっと、それ以上は言うなよ…
. |     (__人__)____
  |     ` ⌒/ ─' 'ー\
.  |       /( ○)  (○)\
.  ヽ     /  ⌒(n_人__)⌒ \
   ヽ   |、    (  ヨ    | つまりFiberはダ・・・
   /    `ー─−  厂   /
   |   、 _   __,,/     \

   / ̄ ̄\
 /   _ノ  \
 |    ( ●)(●) 本当はresumeとyieldを分けて評価したいが、
. |     (__人__) マブダチだから切り分けは無理だろう。
  |     ` ⌒´ノ  常識的に考えて・・・
.  |         }
.  ヽ        }
   ヽ     ノ        \
   /    く  \        \
   |     \   \         \
    |    |ヽ、二⌒)、          \ 

   / ̄ ̄\
 / ノ  \ \
 |  (●)(●) |
. |  (__人__)  | あんたもそう思うだろ?
  |   ` ⌒´  ノ
.  |         }
.  ヽ        }
   ヽ     ノ        \
   /    く  \        \
   |     \   \         \
    |    |ヽ、二⌒)、          \
     ____ 
   /      \ ( ;;;;( 
  /  _ノ  ヽ__\) ;;;;)    
/    (─)  (─ /;;/  これは仕方が無いお・・・。 
|       (__人__) l;;,´   resumeとyieldでかなり時間を食っているとなると、
/      ∩ ノ)━・'/   呼び出し回数を減らか、
(  \ / _ノ´.|  |   アルゴリズムを考え直すか無いお。
.\  "  /__|  |     俺からいえることはこれだけだお・・・。      
  \ /___    

   / ̄ ̄\
 /   _ノ  \
 |    ( ●)(●)
. |     (__人__)  結局それかい
  |     ` ⌒´ノ
.  |         }  ミ        ピコッ
.  ヽ        } ミ  /\  ,☆____
   ヽ     ノ    \  \ /     \ これ以上考えると、
   /    く  \.  /\/ ─    ─ \「けいおん!」のBDを
   |     `ー一⌒)  /   (●)  (●)  \見る時間が無くなるお
    |    i´ ̄ ̄ ̄ \ |      (__人__)     |
               \_   ` ⌒´    /
                /          \
                                 ,.へ
  ___                             ム  i
 「 ヒ_i〉                            ゝ 〈
 ト ノ                           iニ(()
 i  {              ____           |  ヽ
 i  i           /__,  , ‐-\           i   }
 |   i         /(●)   ( ● )\       {、  λ
 ト−┤.      /    (__人__)    \    ,ノ  ̄ ,!
 i   ゝ、_     |     ´ ̄`       | ,. '´ハ   ,!
. ヽ、    `` 、,__\              /" \  ヽ/
   \ノ ノ   ハ ̄r/:::r―--―/::7   ノ    /
       ヽ.      ヽ::〈; . '::. :' |::/   /   ,. "
        `ー 、    \ヽ::. ;:::|/     r'"
     / ̄二二二二二二二二二二二二二二二二ヽ
     | 答 |     お   わ   り       │|
     \_二二二二二二二二二二二二二二二二ノ

皆さんお疲れ様でした。こんな駄作におつきあいいただき、ありがとうございました。
至らない点が多いかと思いますが、そこはお見逃しを・・・。
(ただし、Ruby上での実装に問題がございましたらご指摘ください)

結局は、Fiberは便利だけど、使いすぎると強烈なパフォーマンス低下に悩まされることになりそうです。
Fiber使うときは、キャッシュを用意するなど、できる限りresume・yieldの呼び出しを押さえる必要があります。

最後、簡単(すぎる)まとめをムギから。

                           7⌒ ー-
                           /  /| ,′  ヽ `ヽ
                        / / /-‐ト、{  卜、 ‘,
.      | ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|/´ ̄「 ∧ L 」  }
.      |     ま  と  め      l,ィ扞トl/  ヽト、|     }
.      |                  l ヒ'シ   .ミ、 | ハ   /
        |  ・Fiberは便利   .      |''   .   {t.r}j |/ | /
       |                    | 、   `,,^ } |'
      | ・resumeとyieldはマブ    |、  `    'フ   }{
     ,.⊥、                {.n`! ‐--‐,1|T   八
     }ニY  ・使いすぎるなよ  .    f,二Y´  ̄ト|」」_  /{  ヽ
    rウT′                    {_rこ)  ノ ノ  ,ハ 、
.       ヽ|                 |   }Y´/   / | ヽ }
      「|                     l r'{フ/   /   |  ∨
.       !|                    |ノ ,ハ{  /     ハ
.       l|        ゲル状がいいの♪.l/゚。∨/ /  /} }   }
.      l|                   |    Y´   / ノノ  ,ハ
       |____________l      |    '}/  /
       丶--‐  ´    /      ,|       |   /-‐     }
                          C八        ∧       /
               {         \    イ} }    /