2012-04-20 14 views
18

JRuby 1.6.7(1.9.2モード)を使用して実行するRails 3.2.2アプリケーションがあります。 JRubyのは、使用しての下JRubyの性能

:|:(8.2msをActiveRecordの27.5msビュー) 36msでOK 200を完了:

私は〜40msの中に戻っているMRIルビー1.9.3と、典型的な要求で実行されているサンプルアプリを持っています同じ要求は、ページによって3〜20倍遅くなります。上記の操作と同じ操作で約180msかかる: 180msで200 OK(閲覧:153.0ms | ActiveRecord:24.0ms)

これは正常な性能の違いですか?私はJRubyがMRIとほぼ同じスピードであることを読んだ。結果は私のMacとWindowsサーバで保持されます(残念ながら実行する必要があります)。 Tomcatの下で実行されているWarblerを使ってパッケージ化するのと同じように遅いです。

上記の時間は、JRubyをテストするために作成された基本的なレールアプリからのものです。より複雑なアプリでは、時間はさらに離れています。そのアプリでは、いくつかのページで実行されているルビーコードが増えています。ページがルビーに依存するほど、パフォーマンスの差は大きくなります。 JRubyのチューニングは一切していません。どこから始めるのか分かりません。

私の質問は:これは正常ですか? JRubyをチューニングするにはどうすればよいですか?

答えて

18
Is this a normal performance difference? 
I have read that JRuby is roughly equal on speed with MRI. 

いいえ、それは正常ではありません。 JVMがウォームアップすると、JRubyのRailsリクエストは、通常、Raw実行速度とガベージコレクションの両方で、MRIよりもパフォーマンスが大幅に向上します。

あなたのアプリが誤って設定されているようです。最初にチェックするのはRails自体の設定です.Railsが開発モードでないこと、そして本番環境でconfig.threadsafe!が有効になっていることを確認してください。 Threadsafeモードでは、アプリケーションの実行中にメモリにロードされたRailsの共有コピーが1つしかありません。

また、データベース構成が接続プーリングを利用していることを確認してください。 pool: 20database.ymlに設定します。

最後に、JVMとJRubyの設定を確認してください。両方とも非常に調整可能です。起動時にJVMに十分なメモリが割り当てられていることを確認し、通常のアプリケーションの円滑な操作に十分なメモリを確保する必要があります。そうしないと、JVMは常に早すぎて頻繁にガーベッジ・コレクトを行うことになり、パフォーマンスが大幅に低下します。例えば

控えめにspecced VPSの設定の一部のようなものかもしれません:

-Xmx500m -Xss1024k -Djruby.memory.max=500m -Djruby.stack.max=1024k

...しかし、やみくもに、これらの設定をコピーしないでください!あなたは、あなたのサーバ上で利用可能なメモリリソースに関して、あなたに何が良いかを試して試してみる必要があります。

しかし、JRubyはおそらくMRIで複数のRailsプロセスの合計より少ないメモリしか消費しませんが、1つのJVMプロセスに少しだけ前向きに割り当てる必要があります。JRubyのに寛大で、そしてJRubyのは、あなたがここにJRubyとJVMのチューニングについての詳細を読むことができます

:-)あなたの優しさのためにあなたに報酬を与えるでしょう。https://github.com/jruby/jruby/wiki/PerformanceTuning

更新

にあなたが設定する必要はありません。 config.threadsafe! in Rails 4.0以上;デフォルトではスレッドセーフです。

+0

'production 'モードで実行すると、開発モードに比べて5〜6倍高速に応答します。少なくともそれは私の場合だった。それに気づいてくれてありがとう。 – Aleks

3

JAVA 7でjruby 1.6.8またはjruby 1.7.xにアップグレードしてください!

素晴らしいパフォーマンス。

私たちは同じ問題を抱えていましたが、今は非常に高速です(バージョンを切り替えるだけで)。

+2

私は同じ悪い公演をしています。 Java 7&Jruby 1.7を試してみました。新鮮なレールアプリは、MRIの強力な現在のプロジェクトよりも遅いです。エルグ – m4tm4t

4

私は同じ動作を見ていますが、JRubyがウォーミングアップにかなり長い時間を要することを覚えておいてください。私は実際にJRubyが最終的に追いつくことをやや楽観的です。

いくつかのオプションを設定することで、この「ウォーミングアップ」をより迅速に行うことができます。 - ルビー> Javaバイトコードコンパイラは、次のenv VAR設定することで、最初の呼び出しですべてのメソッドをコンパイルするJITに教えることができます。数回Railsのページを更新した後、私にとって

export JRUBY_OPTS="-J-Djruby.jit.threshold=1 -J-Djruby.jit.max=16384"

を、それはまだ2ですMRI Rubyよりも-3倍遅いですが、以前よりも少なくとも3倍高速です。

Javaランタイムは、Javaバイトコードを同様の方法でマシンコードにコンパイルするJITですが、このJITは、サーバーランタイムを使用するときにメソッドが10.000xで呼び出されるまでは実行されません。これはconfigured as wellです。これらのオプション付き

export JRUBY_OPTS="-J-Djruby.jit.threshold=10 -J-Djruby.jit.max=16384 -J-XX:CompileThreshold=10" -J-XX:ReservedCodeCacheSize=128M"

、Railsの上のJRubyがMRIよりも同等以上のパフォーマンスについて提供します。

これらのオプションはちょっとしたベンチマークのためだけのものです。実際には、JITコンパイルをこれを積極的に実行することはほとんど常に悪い考えです。 JITでコードをコンパイルするのに貴重な時間とメモリを浪費していますが、これは数回しか実行されない可能性があります。しかし、最終的な実行に基づいてJRubyのパフォーマンスが期待どおりに向上する可能性があります。

これがあなたに役立つかどうかを教えてください。