@ledsun blog

無味の味は佳境に入らざればすなわち知れず

Ruby 3.0のJITの特性

Ruby 3.0のJITのすごさを体験する - @ledsun blogスクリプトは引数で計算回数を指定することができます。 5000万回計算するとJITありはなしの2倍近い速度になりました。 施行回数を減らすとどうなるでしょうか?

~ time ruby hoge.rb 500
-0.169075164
-0.169021528

________________________________________________________
Executed in  149.25 millis    fish           external
   usr time   89.73 millis  108.00 micros   89.63 millis
   sys time   48.53 millis  987.00 micros   47.54 millis

~ time ruby --jit hoge.rb 500
-0.169075164
-0.169021528

________________________________________________________
Executed in  728.38 millis    fish           external
   usr time  886.74 millis  104.00 micros  886.64 millis
   sys time  126.96 millis  842.00 micros  126.12 millis

JITなしのほうが5倍速いです。 RubyKaigiでkokubunさんが解説されていました。

youtu.be

「--jitは2秒程度だとかえって遅くなる」例に該当しそうです。 原因は次の2つです。

  1. JITコンパイルしている間遅くなる
  2. Rubyを停止するときにJITコンパイルのスレッドを待つ

計算回数を徐々に増やしていく

5000回

~ time ruby hoge.rb 5000
-0.169075164
-0.169020000

________________________________________________________
Executed in  168.41 millis    fish           external
   usr time  107.60 millis  108.00 micros  107.49 millis
   sys time   50.76 millis  846.00 micros   49.91 millis

~ time ruby --jit hoge.rb 5000
-0.169075164
-0.169020000

________________________________________________________
Executed in  716.74 millis    fish           external
   usr time  839.24 millis  125.00 micros  839.12 millis
   sys time  139.06 millis  988.00 micros  138.07 millis

50000回

~ time ruby hoge.rb 50000
-0.169075164
-0.169078071

________________________________________________________
Executed in  379.52 millis    fish           external
   usr time  315.76 millis  122.00 micros  315.64 millis
   sys time   52.42 millis  947.00 micros   51.48 millis

~ time ruby --jit hoge.rb 50000
-0.169075164
-0.169078071

________________________________________________________
Executed in  508.90 millis    fish           external
   usr time  744.36 millis  128.00 micros  744.24 millis
   sys time  123.96 millis  946.00 micros  123.01 millis

実行時間が1秒以下の場合はJITなしの方が速いようです。

500000回

~ time ruby hoge.rb 500000
-0.169075164
-0.169096567

________________________________________________________
Executed in    2.42 secs    fish           external
   usr time    2.34 secs    0.12 millis    2.34 secs
   sys time    0.06 secs    1.03 millis    0.06 secs

~ time ruby --jit hoge.rb 500000
-0.169075164
-0.169096567

________________________________________________________
Executed in    2.47 secs    fish           external
   usr time    4.29 secs    0.13 millis    4.29 secs
   sys time    0.32 secs    1.01 millis    0.32 secs

実行時間が2秒を越えるとJITありなして実行時間時間に差がなくなりました。 動画の通りです。

5000000回

~ time ruby hoge.rb 5000000
-0.169075164
-0.169083134

________________________________________________________
Executed in   22.45 secs    fish           external
   usr time   22.26 secs  135.00 micros   22.26 secs
   sys time    0.12 secs  975.00 micros    0.11 secs

~ time ruby --jit hoge.rb 5000000
-0.169075164
-0.169083134

________________________________________________________
Executed in   13.32 secs    fish           external
   usr time   15.07 secs    0.13 millis   15.07 secs
   sys time    0.35 secs    1.04 millis    0.35 secs

実行時間が20秒を越えるとJITによる実行時間削減の効果が明確に得られるようです。