21

JRuby 1.6.7(1.9.2モード)を使用して実行しようとしているRails3.2.2アプリケーションがあります。

サンプルアプリをMRIruby1.9.3で実行していますが、通常のリクエストは約40ミリ秒で返されます:36ミリ秒で200 OKを完了しました(ビュー:27.5ミリ秒| ActiveRecord:8.2ミリ秒)

JRubyでは、同じリクエストを使用すると、ページによって3〜20倍遅くなります。上記と同じ操作の場合、約180msかかります:180msで200 OKを完了しました(ビュー:153.0ms | ActiveRecord:24.0ms)

これは通常のパフォーマンスの違いですか?JRubyの速度はMRIとほぼ同じだと読んだことがあります。結果は私のMacとWindowsサーバーで保持されます(残念ながら実行する必要があります)。Tomcatで実行されているWarblerでパッケージ化するのも同じくらい遅いです。

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

だから私の質問は:これは正常ですか?JRubyを調整するにはどうすればよいですか?

4

3 に答える 3

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

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

アプリの設定が間違っているようです。最初に確認することは、Rails 自体の構成です。Rails が開発モードになっておらず、config.threadsafe!本番環境で有効になっていることを確認してください。スレッドセーフ モードでは、アプリの実行時にメモリに読み込まれる Rails の共有コピーが 1 つだけになります。

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

最後に、JVM と JRuby の設定を確認します。どちらも高度に調整可能です。起動時に JVM に十分なメモリが割り当てられていることを確認してから、アプリケーションの通常の円滑な操作に十分なメモリがあることを確認する必要があります。そうしないと、JVM は常に時期尚早かつ頻繁にガベージ コレクションを実行するよう強制され、パフォーマンスが大幅に低下します。

たとえば、適度な仕様の VPS の設定の一部は次のようになります。

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

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

とはいえ、JRuby はおそらく MRI での複数の Rails プロセスの合計よりも少ないメモリを消費しますが、単一の JVM プロセスにもう少し多くのメモリを事前に割り当てる必要があることは間違いありません。JRuby に寛大に接してください。JRuby はあなたの親切に報いるでしょう :-)

JRuby と JVM のチューニングについて詳しくは、https ://github.com/jruby/jruby/wiki/PerformanceTuning をご覧ください。

アップデート

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

于 2012-04-23T16:09:24.783 に答える
4

同じ動作が見られますが、JRuby のウォームアップにはかなり長い時間が必要であることに注意してください。私は実際、JRuby が最終的に追いつくだろうと少し楽観的です。

いくつかのオプションを設定することで、この「ウォーミングアップ」をより速くすることができます。Ruby -> Java Bytecode コンパイラは、次の環境変数を設定することにより、最初の呼び出しですべてのメソッドを JIT コンパイルするように教えることができます。

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

私にとっては、Rails ページを数回更新した後でも、MRI Ruby よりも 2 倍から 3 倍遅くなりますが、以前より少なくとも 3 倍速くなりました。

また、Java ランタイムは、Java バイトコードをマシン コードに同様の方法でコンパイルする JIT であることに注意してください。ただし、この JIT は、サーバー ランタイムを使用する場合、メソッドが 10.000x で呼び出されるまで開始されません。これも構成できます。

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

これらのオプションを使用すると、JRuby on Rails は MRI とほぼ同じかそれ以上のパフォーマンスを発揮します。

これらのオプションはせっかちなベンチマーク専用であることに注意してください。実際には、JIT コンパイルをこれほど積極的に実行することは、ほとんどの場合、悪い考えです。数回しか実行されないコードの JIT コンパイルに、貴重な時間とメモリを浪費しています。ただし、最終的な JRuby のパフォーマンスが、最初の実行に基づく予想よりも優れている可能性があることを示しています。

これがうまくいくかどうか教えてください。

于 2013-01-29T13:48:04.470 に答える
3

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

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

同じ問題がありましたが、現在は非常に高速です (バージョンを切り替えるだけです)。

于 2012-12-13T11:23:22.217 に答える