Rubyのファイバーは遅いか?

この記事は Independent Advent Calendar 2015 の記事です。

ruby fiber で検索すると「遅い」というサジェストが出てきたりするようですが、実際にそれほど重いものでしょうか?

そもそも比較対象がよくわからない点もありますが、コルーチン的な「並列には動かない並行処理」のサンプルで、スレッドの場合と比較してみました(そもそもスレッドのほうが圧倒的に重いだろ、という所ではありますが、一応どの程度か見る意味はあると思います)。

作成したサンプルは、こちら https://gist.github.com/metanest/c7bbf960e5d7a0cf963d に置きました。

timeで計測すると、

$ time ./sample_fiber.rb

real    0m1.868s
user    0m0.676s
sys     0m1.176s
$ time ./sample_thread_q.rb

real    0m12.835s
user    0m9.388s
sys     0m7.504s
$ time ./sample_thread_w.rb

real    0m11.854s
user    0m8.054s
sys     0m7.494s

という感じで、手元のFreeBSD(amd64)ではスレッドの5倍程度はファイバーの方が速い、という結果になっています。

また、並行処理として同じように動作しない可能性があるのでここには挙げませんでしたが Thread.pass を使ったものについても同程度の傾向となっていますので、この差はほぼ、ファイバーの transfer と、スレッドの切り替えとのオーバーヘッドの差と見て良いものと思われます。