最近のMRI Rubyリリースでは、ファイルを添付する際に大幅な速度低下が見られます。
たとえば、ロード時の平凡なレールアプリケーションでは約2200回必要です-これはグラフの右側にあります。 全然良くない。 1.9.2では、アプリケーションは20秒で起動し、1.9.3ではすでに46です。遅すぎます!
これにはいくつかの理由がありますが、主な理由はrequireアルゴリズムであり、次のようになります。
def require(file) $loaded.each do |x| return false if x == file end load(file) $loaded << file end
すべてのブレーキはサイクルから発生し、接続するファイルが多いほど、すべてが遅くなります。 ブレーキサイクルを次のようなものに置き換える1.9.3のパッチを作成しました。
def require(file) return false if $loaded[file] load(file) $loaded[file] = true end
これにより、おおよそ次の結果が得られます。
もっといい!
これらは空のファイルを接続するための合成テストのプロットですが、パッチは実際のプロジェクトで加速を提供します。 アプリケーションは約10秒でロードされます。 20.空のアプリケーションは一般に1.1秒でロードされ、1.8.7よりも高速です。
パッチ方法
ここではすべてが非常に簡単です。RVMがインストールされていれば、10分以内に完了します。
# cd /your/rails/app time script/rails runner "puts 1" # ruby curl https://gist.github.com/raw/996418/e2b346fbadeed458506fc69ca213ad96d1d08c3e/require-performance-fix-r31758.patch > /tmp/require-performance-fix.patch rvm install ruby-head --patch /tmp/require-performance-fix.patch -n patched # ... — 8 MBP # cd /your/rails/app rvm use ruby-head-patched gem install bundler --no-rdoc --no-ri bundle time script/rails runner "puts 1"
どうすれば手伝うことができますか
メイントランクに含まれる前に、パッチに可能な限り注意を払う必要があります。 次の場合に役立ちました:
- 私たちは彼らのアプリケーションでパッチを試し、コメントのベンチマークの実行時間を取り消しました。
- githubのプルリクエストのコードを見ました(言語C、しかし誰も怖がらないことを願っています)
- Windowsで試した
- 発見した報告済みのバグ
次は何ですか
このパッチを1.9.3に含めることはまだ先のことであり、多くの作業が残っていると思いますが、これはレール上のアプリケーションの立ち上げを加速するための多くのステップの最初のステップです。 何らかの理由で多くの時間を費やすBundlerとRubyGemsもあります-それらの内部を調べたいです。
同様の問題があるため、このパッチをJRubyに移植する予定です。 ルビニウスでは、すべてが最初から順番に並んでいるようです。