Ruby 1.9.0がなぜ遅いか調べてみた
id:kwatchさんの日記で、Ruby 1.9がRuby 1.8より遅い例が載っていました(http://d.hatena.ne.jp/kwatch/20080304/1204646782)。
とても興味深かったのでどうして遅いか調べてみました。記事中のtest2.rbを実行して、そのプロファイルを採ってみました。
Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls s/call s/call name 11.20 0.70 0.70 8200035 0.00 0.00 rb_enc_cr_str_buf_cat 10.56 1.36 0.66 1100052 0.00 0.00 vm_eval 5.12 1.68 0.32 9309234 0.00 0.00 rb_newobj 3.36 1.89 0.21 8285264 0.00 0.00 rb_str_free 3.36 2.10 0.21 8200016 0.00 0.00 rb_str_append 3.36 2.31 0.21 458 0.00 0.00 garbage_collect 2.72 2.48 0.17 1100007 0.00 0.00 invoke_block 2.40 2.63 0.15 2800033 0.00 0.00 ruby_xrealloc2 2.24 2.77 0.14 8200033 0.00 0.00 rb_str_buf_append 2.08 2.90 0.13 6300202 0.00 0.00 str_replace_shared 2.08 3.03 0.13 2029344 0.00 0.00 st_lookup 2.08 3.16 0.13 1000000 0.00 0.00 rb_fix2str 1.92 3.28 0.12 2800048 0.00 0.00 ruby_xrealloc 1.92 3.40 0.12 2001933 0.00 0.00 rb_str_hash_cmp 1.76 3.51 0.11 2004693 0.00 0.00 hash 1.44 3.60 0.09 8200509 0.00 0.00 str_independent 1.44 3.69 0.09 6304972 0.00 0.00 rb_enc_internal_set_index 1.44 3.78 0.09 2102113 0.00 0.00 ruby_xmalloc2 1.28 3.86 0.08 6300051 0.00 0.00 rb_str_new3 以下略
やはり文字列のエンコードがオーバヘッドになっているようです。割合が小さいので省略していますが、他にもencが名前に付いた関数が結構な数あってそれらを足すと全部で18%位になります。一方、VM化によるスピードアップはほとんどvm_evalの部分だけだと思いますので、あんまり速度向上の伸びしろが無いなと思います。
やっぱり、Webアプリケーションみたいな文字列処理では現状では1.8の方がいいのかなと思いました。私は、ループぐるぐる、Float演算使いまくりって感じの使い方が主なので、1.9を手放すなんてことは考えられないのですが・・・。