miauのブログ

はてなダイアリー「miauの避難所」をはてなブログに移行しました

Windows での ruby の動作を速くしたい (1)

Rails で開発中のシステムがあるんですけど、Windows での ruby の動作が遅くてイマイチ開発がはかどりません。ページを表示するのに 2〜3 秒かかったりとか。

ruby は動作が遅いって言われてるし仕方ないかー」と諦めて開発してたんですけど、VMware のゲスト OS として動いている Linux 上では、ページの表示が 0.3 秒程度で終わっていて。Apache + Passenger + Ruby Enterprise Edition の環境とはいえ、ゲスト OS 上のほうが速いってどういうこと?

Windows 上でもがんばればもっと速く動作するんじゃないの?ということで色々試してみました。まあタイトルが「したい」で止まっていることからわかるように、結局成功していないんですけど。

      • -

・・・と、あらかた記事を書き終わったところで、ちゃんと検証している方を見つけてしまいました。

私の方は拙い検証しかしてなくてちょっとアレですけど、誰かの参考になるかもしれないので(と自分に言い聞かせて)、記事はあげておきます。

まず試したこと

とりあえず思いついたのは以下の 3 つです。

  1. RAILS_ENV=production で動作させる
    • デバッグログが出なくなるので常用はできないですが、これで快適になるなら・・・
  2. Mongrel でなく WEBrick で動作させる
    • Mongrel のほうが速いはずだけど、思い込みとかあるかもしれないので
  3. ruby 1.9.x や JRuby で動作させてみる
    • 1.8.x よりも速いはずなので。以前単純なアルゴリズムで試した際は、1.9.x は数割程度、JRuby は 5 倍程度高速だったので、これが本命。

これらを試そうとしたんですが、1.9.x は文字コードの扱いが変わっているようで、ソースに手を入れないと動作しない雰囲気なのでやめておきました。1.8 と呼んでいるのは、InstantRails 付属の

ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-mswin32]

こういうバージョンです。

さて、結果を。

development production
ruby 1.8 mongrel 3 s 2.26 s
ruby 1.8 webrick 3.83 s 2.4 s
JRuby webrick 5.7 s 2.26 s

RAILS_ENV=production は数割速くなってますけど、Linux での速度に比べるとぱっとしません。WEBrick もまあ似たようなものです。
JRuby のほうは動作速度変わりませんでした。シンプルなケースだとかなり速いんですけど・・・なかなかうまくいかないものですね。

ググってみる

2010年5月時点では、「Windows Ruby 遅い」みたいな感じでググると、

このページがヒットして。リンクをたどっていくと、

のようにいくつか情報がありました。

ファイルシステムの問題?

NTFS が遅い」というような記載をがあったので、NTFS 以外のファイルシステムで動作確認を試みました。いくつかは見当外れでしたが、一応全部書いておきます。

ちなみにここでの動作確認方法は、InstantRails やら Rails のアプリやらをすべて作成したディスクに放りこむ→Mongrel をそこで起動してページアクセスする、という方法。

(1) VHD でマウントしてみる

NTFS が遅いなら、仮想ディスクを使って実施にファイルアクセスを発生させなければいいんじゃない?ということで、VHD を試してみました。

ということで Windows7 で .vhd ファイルを作成。

Windows XP 上にマウントと。やってから気づいたんですが、ディスクをマウントした状態になるので、フォーマットしてからじゃないとファイル置いたりはできないんですね・・・。結局 NTFS でフォーマットしたので、パフォーマンスには差はありませんでした。

(2) RAM Disk を使ってみる

RAM Disk での動作も確認してみます。ソフトはいくつかありましたが、今回は

こちらを使いました。

File System で「RAW」って選べるから、ファイルシステムの影響受けないと期待してたんですけど、フォーマットされてない状態でディスクを作成するだけ(VHD と同じ状態)のようで。結局 NTFS でフォーマットして、動作速度は変化せず。

まあ通常の状態でもキャッシュが効いていて、ディスクの I/O で遅くなっているわけではない、という確認にはなりました。

(3) ext3 でマウントしてみる

Windows から ext3 を利用するツールについては、

に比較があって、あとここに載ってないツールとして Ext2IFS というのもありました。

今回は読み書きしたかったので ext2fsd と Ext2IFS の二つを試してみました。

まず、ext3パーティションがなかったので、

ext3パーティションを作成して。作成したパーティションを ext2fsd や Ext2IFS でマウント、と。(※ext2 のマウントツールはどちらも不安定で、すぐにアンインストールしてしまったので、細かい操作は覚えてません・・・。)

動作速度のほうですが、特に変化はありませんでした。NTFS というファイルシステムが問題なのではないということですね。

もし ファイルシステムが遅いなら Dokan と KVS で独自ファイルシステムでも作ろうと思っていたんですけど、この方法では解決しない気がします。ext3 でも動作が遅いということは、Windows の File API が呼ばれてる時点で処理が遅くなっている予感が・・・。

読み込むファイルを減らしてみる

require 'rubygems' 後の require では、GEMS_ROOT 配下のディレクトリすべてから該当のパッケージを探してこようとします。これでは大量のファイルアクセスが発生するのは避けられないわけですが。

じゃあ実際に読み込まれるファイルを減らしてみたらどうなるか試してみました。

不要なライブラリ削除

まず、ライブラリの旧バージョン等が結構入っていたので、これを削ってみます。

gem cleanup

これだけでは動作速度は変わらず。

読み込む拡張子を減らしてみる

ruby\lib\ruby\site_ruby\1.8\rubygems.rb に

  def self.suffixes
    ['', '.rb', '.rbw', '.so', '.bundle', '.dll', '.sl', '.jar']
  end

こんな処理があって、余計なファイルも探しに行っている気がしますので、ちょっと減らしてみます。とりあえず、

  def self.suffixes
    ['', '.rb', '.so', '.dll']
  end

こんな感じで。

Process Monitor 等で確認すると、走査するファイルは半分程度に減っているみたいなんですが・・・動作速度はほとんど変わりませんでした。ファイル走査以外の処理も遅いということ・・・?