- GraalVM for JDK 23 (最新)
- GraalVM for JDK 24 (早期アクセス)
- GraalVM for JDK 21
- GraalVM for JDK 17
- アーカイブ
- 開発ビルド
パフォーマンス問題の報告
TruffleRubyのパフォーマンスが他のRuby実装よりも低いと感じた場合は、ご報告いただけると幸いです。パフォーマンスに関する問題が発生した場合は、GitHubでお知らせください。
互換性ガイドには、速度が遅いことが知られており、今後高速化の見込みがない機能がいくつかリストされています。
よくある問題とその理由 #
TruffleRubyは、Rubyプログラムを最適化するために非常に高度な技術を使用しています。これらの最適化には時間がかかるため、TruffleRubyはウォームアップするまで、他の実装よりもはるかに遅いことがよくあります。
また、TruffleRubyはプログラムの「安定状態」を見つけ出し、必要のない部分ではRubyの動的性を自動的に削除しようとします。しかし、この安定状態が乱れると、TruffleRubyが新しい安定状態に適応するまで、パフォーマンスが低下します。
もう1つの問題は、TruffleRubyは不要な作業(不要な計算や作業を含まないループなど)を非常にうまく削除することです。
これらの問題により、TruffleRubyのベンチマークは困難になります。これは私たち特有の問題ではなく、多くの高度な仮想マシンにも当てはまりますが、ほとんどのRuby実装はまだこれらの問題を示すのに十分強力な最適化を実行していないため、Rubyコミュニティの一部のユーザーにとっては新しい問題かもしれません。
Oracle GraalVMの使用 #
TruffleRubyの速度を試すには、Oracle GraalVMを使用してください。
JVM設定の使用 #
最高のピークパフォーマンスを得るには、--jvm
を使用してJVM設定を使用してください。デフォルトのネイティブ設定は起動が速くなりますが、同じピークパフォーマンスには到達しません。ただし、後で説明するbenchmark-ips
のような適切なベンチマークツールを使用してベンチマークを実行する必要があります。そうでなければ、ウォームアップ時間が長いため、ベンチマークでTruffleRubyの真のパフォーマンスを確認できません。単純なタイマーを使用してwhileループを実行するだけの単純なベンチマークを作成する場合は(お勧めしませんが)、起動時間とウォームアップ時間を短縮するために、デフォルトのネイティブモードを使用してください。
基本的なパフォーマンス問題の確認方法 #
TruffleRubyのパフォーマンスを調べるときは、常に--engine.TraceCompilation
フラグを使用して実行することをお勧めします。コンパイルエラーまたは同じメソッドの繰り返しコンパイルが表示された場合は、何かが意図したとおりに機能していないことを示しており、その理由を調べたり、私たちに助けを求めたりする必要があるかもしれません。このフラグを使用せずに実行すると、TruffleRubyはエラーを回避しようとするため、問題が発生していることがわかりません。
パフォーマンスベンチマークの書き方 #
TruffleRubyチームは、benchmark-ips
を使用してTruffleRubyのパフォーマンスを確認することをお勧めします。benchmark-ips
からのレポートを使用して潜在的なパフォーマンスの問題を報告すると、私たちにとって作業が容易になります。
ベンチマークは次のようになります。
require 'benchmark/ips'
Benchmark.ips do |x|
x.iterations = 2
x.report("adding") do
14 + 2
end
end
benchmark-ips
のx.iterations =
拡張機能を使用して、benchmark-ips
のウォームアップサイクルと測定サイクルを2回実行し、結果が安定しており、十分なウォームアップが提供されていることを確認します(x.warmup = 5
で調整できます)。
次のような結果が表示されます。
Warming up --------------------------------------
adding 20.933k i/100ms
adding 1.764M i/100ms
Calculating -------------------------------------
adding 2.037B (±12.7%) i/s - 9.590B in 4.965741s
adding 2.062B (±11.5%) i/s - 10.123B in 4.989398s
最後の行を見てみましょう。これは、TruffleRubyがこのブロックの20億6200万回の反復を1秒間に実行し、誤差範囲は±11.5%であることを示しています。
Rubiniusなどの実装と比較してみましょう。
Warming up --------------------------------------
adding 71.697k i/100ms
adding 74.983k i/100ms
Calculating -------------------------------------
adding 2.111M (±12.2%) i/s - 10.302M
adding 2.126M (±10.6%) i/s - 10.452M
ここでは、TruffleRubyのパフォーマンスはRubiniusよりも1000倍高速であると説明できます。それは非常に多く見えるかもしれません。実際には、TruffleRubyがベンチマークを最適化しているということです。この効果は、最適化できない複雑なコードではそれほど顕著ではありません。
最終的な技術的な注記:ブラックホールと値プロファイリング #
他の言語のベンチマークツールの中には、「ブラックホール」と呼ばれる機能を持つものがあります。これらは値を囲み、実際には定数であっても実行時に変数のように見えるようにするため、最適化によって削除されず、それを使用する計算が実際に実行されます。ただし、TruffleRubyは広範な値プロファイリング(値のキャッシングと定数への変換)を使用しているため、ソースで値を変数のように見せる場合でも、中間段階で値プロファイルされる可能性が高いです。一般的に、重要な機能を手動で無効にする注釈を追加するのではなく、値プロファイリングを自然に無効にするより複雑なベンチマークの方が好ましいです。