やる夫が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八 ∧ / { \ イ} } /