逆に言うと、Rubyの文字列型の内部実装がropeになれば、freezeしてもしなくても変わらない速度が出るようになって、結局freezeする必要なんてなかったんやーで丸く収まるんじゃないの?と思いました #雑な感想
— Kazuho Oku (@kazuho) October 6, 2015
とツイートしたところ、処理系の中の人から@kazuho 文字列を弄る話じゃなくて、文字列の identity の話なので、ちょっと関係ないかなぁ、と
— _ko1 (@_ko1) October 6, 2015
みたいなツッコミをもらって、うっすみません…ってなってRuby VMのコードを読むことになったわけです。で、まあ、いくつか気になる点があったので手をつけてしまいました。
1. オブジェクト生成のホットパスの最適化
ホットスポットだとされていたところのコードを読んでると、オブジェクト生成の際に走る関数が割と深いのが問題っぽかった。通常実行されるパスは短いから、それにあわせて最適なコードがはかれるようにコードを調整すれば速くなるはず!!!
とコンセプトコードを書いて投げたら取り込まれた。やったね!!!
と思ったら、ほとんど速くなってないっぽい。これは悲しい…ということで、細かな修正を依頼。
このPR適用すると、問題のマイクロベンチマークが3%〜5%くらい速くなるっぽい。
2. ヒープページのソートをやめる
通常実行される側をいじっても期待ほど速度が上がらなかったので、これは遅い側に原因があるかも…って見ていて気になったのが、ヒープページをソートする処理。現状のRubyは、オブジェクトを格納する「ヒープページ」を16KB単位で確保するんだけど、これを逆参照できるように、アドレスでソートした一覧を持ってる。この構築コストがでかい。
で、これをヒープに書き直してみたところ、rdocを使ったベンチマークで2〜3%の高速化が確認できたので報告。
.@_ko1 気になったので、heap tableを雑にハッシュ化してみましたが、rdocで2〜3%実行時間が減ります(高速化します)ね https://t.co/CJhierZZN3
— Kazuho Oku (@kazuho) October 7, 2015
ただ、今日のRubyは、(昔読んだ記事とは異なり)ヒープページが16KB単位でアラインされているということなので、ヒープを使うよりもビットマップを使うべき案件。
3. スイープの最適化
ヒープページのソートを書き直したあとでプロファイラの出力を眺めていたら、GCのスイープ処理が重たいことに気づいた。コードを読んだところ、分岐回数と呼出深度の両面で改善が望めそうだったので、ざっくりやったところ、やはり2〜5%程度実行時間の短縮ができた。ので、これはPRとして報告。
この3つを組み合わせると、rdocみたいな実アプリケーションの実行時間が、手元で5%以上縮みそう!注1 ってことで満足したのがここ二日間の進捗です!!!!!!! なんかいろいろ滞っているような気がしますがすみああおえtぬさおえうh
これからは雑なツイートを慎みたいと思います。
注1: バグがなければ!!
No comments:
Post a Comment