@ledsun blog

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

ruby/debugをつかってみる

rubykaigi.org

を見ました。 良い機会なのでruby/debugを素振りしてみます。 次のRubyスクリプトを書きます。

require 'debug'

def baz n
  n
end

def bar n
  baz n
end

def foo n
  bar n
end

binding.b
result = foo(100)
p result

実行してみましょう。

ledsun@MSI:~/ruby-debugger►ruby main.rb
[10, 17] in main.rb
    10|
    11| def foo n
    12|   bar n
    13| end
    14|
=>  15| binding.b
    16| result = foo(100)
    17| p result
=>#0    <main> at main.rb:15

binding.b と書いたところで止まります。 実はカラフルに表示されています。 スクリーンショットを張ります。

main.rbを実行した直後

sを入力してEnterキーを押します。

sを入力してEnterキーを押したところ

binding.bの次の行に移動しました。 sstepコマンドです。 もう一度、sを入力してEnterキーを押します。

もう一度sを入力してEnterキーを押したところ

foo関数の中に入りました。 関数の中に入らずに次の行に進むにはnextコマンドをつかいます。 いまはためしません。

stepコマンドをつかってどんどん関数の中に入っていきます。

baz関数の中まで入ったところ

なにやら下のほうにframeという情報が表示されています。

=>#0    Object#baz(n=100) at main.rb:4
  #1    Object#bar(n=100) at main.rb:8
  # and 2 frames (use `bt' command for all frames)

btと入力してEnterキーを押してみます。

btを入力してEnterキーを押したところ

baz, bar, fooと中に入った関数が順に表示されます。 up, down, frameコマンドで表示されたframeを移動できるらしいです。 この辺からよくわからなくなりました。

Ruby複数の実装でたらい回しベンチマーク

sumim.hatenablog.com

の追試です。 複数のRuby実装で速さの違いを比べてみます。

スクリプト

require 'benchmark'

def tak(x, y, z)
  if x > y then
    tak(tak(x-1, y, z), tak(y-1, z, x), tak(z-1, x, y))
  else
    y
  end
end

Benchmark.bm do |x|
  x.report do
    tak(14, 7, 0)
  end
end

Ruby 3.1.2preview2

ledsun@MSI:~/tarai►ruby -v tarai.rb
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
       user     system      total        real
  15.766919   0.000000  15.766919 ( 15.767049)

Ruby 3.1.2preview2 with YJIT

ledsun@MSI:~/tarai►ruby -v --jit tarai.rb
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) +YJIT [x86_64-linux]
       user     system      total        real
   3.669399   0.000000   3.669399 (  3.669449)

Ruby 3.1.2preview2 with MJIT

ledsun@MSI:~/tarai►ruby -v --mjit tarai.rb
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) +MJIT [x86_64-linux]
       user     system      total        real
   5.770545   0.011228   6.710264 (  5.778556)

Ruy 3.1.2

ledsun@MSI:~/tarai►ruby -v tarai.rb
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
       user     system      total        real
  14.975424   0.000000  14.975424 ( 14.975669)

Ruby 3.1.2 with YJIT

ledsun@MSI:~/tarai►ruby -v --jit tarai.rb
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) +YJIT [x86_64-linux]
       user     system      total        real
   4.376260   0.000542   4.376802 (  4.376845)

Ruby 3.1.2 with MJIT

ledsun@MSI:~/tarai►ruby -v --mjit tarai.rb
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) +MJIT [x86_64-linux]
       user     system      total        real
   6.358203   0.000000   7.104936 (  6.356328)

jRuby

ledsun@MSI:~/tarai►ruby -v tarai.rb
jruby 9.3.7.0 (2.6.8) 2022-08-16 c79ef237e0 OpenJDK 64-Bit Server VM 11.0.16+8-post-Ubuntu-0ubuntu120.04 on 11.0.16+8-post-Ubuntu-0ubuntu120.04 +jit [x86_64-linux]
       user     system      total        real
   6.980000   0.000000   6.980000 (  6.335983)

TruffleRuby

ledsun@MSI:~/tarai►ruby -v tarai.rb
truffleruby 22.2.0, like ruby 3.0.3, GraalVM CE Native [x86_64-linux]
       user     system      total        real
   5.272819   0.284125   5.556944 (  4.726222)

感想

いずれのJITも優秀です。 再起呼び出しはJITが効きやすいのでしょうか?

Ruby 3.2.0-preview2

rbevnとruby-buildを使ってRuby 3.2.0-preview2をインストールします。

ledsun@MSI:~►rbenv install 3.2.0-preview2
To follow progress, use 'tail -f /tmp/ruby-build.20220909111902.4631.log' or pass --verbose
Downloading ruby-3.2.0-preview2.tar.gz...
-> https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.0-preview2.tar.gz
Installing ruby-3.2.0-preview2...

BUILD FAILED (Ubuntu 20.04 using ruby-build 20220909)

Inspect or clean up the working tree at /tmp/ruby-build.20220909111902.4631.NjJV3L
Results logged to /tmp/ruby-build.20220909111902.4631.log

Last 10 log lines:
*** Fix the problems, then remove these directories and try again if you want.
make[1]: Leaving directory '/tmp/ruby-build.20220909111902.4631.NjJV3L/ruby-3.2.0-preview2'
Generating RDoc documentation
/tmp/ruby-build.20220909111902.4631.NjJV3L/ruby-3.2.0-preview2/lib/yaml.rb:3: warning: It seems your ruby installation is missing psych (for YAML output).
To eliminate this warning, please install libyaml and reinstall your ruby.
uh-oh! RDoc had a problem:
cannot load such file -- psych

run with --debug for full backtrace
make: *** [uncommon.mk:590: rdoc] Error 1

失敗しました。

please install libyaml

とあるのでlibyamlをインストールします。

ledsun@MSI:~►sudo apt install libyaml-dev
Reading package lists... Done
Building dependency tree
Reading state information... Done
Suggested packages:
  libyaml-doc
The following NEW packages will be installed:
  libyaml-dev
0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
Need to get 58.2 kB of archives.
After this operation, 257 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu focal/main amd64 libyaml-dev amd64 0.2.2-1 [58.2 kB]
Fetched 58.2 kB in 2s (32.3 kB/s)
Selecting previously unselected package libyaml-dev:amd64.
(Reading database ... 81490 files and directories currently installed.)
Preparing to unpack .../libyaml-dev_0.2.2-1_amd64.deb ...
Unpacking libyaml-dev:amd64 (0.2.2-1) ...
Setting up libyaml-dev:amd64 (0.2.2-1) ...

libyamlのインストールに成功しました。 再度Ruby 3.2.0-preview2をインストールしてみます。

ledsun@MSI:~►rbenv install 3.2.0-preview2
To follow progress, use 'tail -f /tmp/ruby-build.20220909112614.18591.log' or pass --verbose
Downloading ruby-3.2.0-preview2.tar.gz...
-> https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.0-preview2.tar.gz
Installing ruby-3.2.0-preview2...
Installed ruby-3.2.0-preview2 to /home/ledsun/.rbenv/versions/3.2.0-preview2

成功しました。 バージョンをみてみましょう。

ledsun@MSI:~[1]►rbenv local 3.2.0-preview2
ledsun@MSI:~►ruby -v
ruby 3.2.0preview2 (2022-09-09 master 35cfc9a3bb) [x86_64-linux]

うまくいきました。

もののついでにjRubyでもπを繰り返し計算してみる

JITが効くまでに時間が掛かるのではないか? - @ledsun blog でTruffleRubyを計測したスクリプトがあります。 そのまま流用してjRubyも計測してみます。

スクリプト

require "bigdecimal"
require "benchmark"

def pi
  prec = 100
  conv = 3
  a = BigDecimal("1")
  b = BigDecimal("1") / BigDecimal("2").sqrt(prec)
  t = BigDecimal("1") / 4
  p = BigDecimal("1")

  for n in 1..conv do
    an = (a + b) / 2
    b = (a * b).sqrt(prec)
    t -= p * (an - a) * (an - a)
    p *= 2
    a = an
  end
end

Benchmark.bm do |x|
  x.report do
    ARGV[0].to_i.times do 
      pi
    end
  end
end
rbenv local 3.1.2
ruby --version
ruby pi.rb $1
rbenv local jruby-9.3.7.0
ruby --version
ruby pi.rb $1

結果

ledsun@MSI:~/ruby-pi►./run_jruby.sh 1
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
       user     system      total        real
   0.004461   0.000000   0.004461 (  0.004499)
jruby 9.3.7.0 (2.6.8) 2022-08-16 c79ef237e0 OpenJDK 64-Bit Server VM 11.0.16+8-post-Ubuntu-0ubuntu120.04 on 11.0.16+8-post-Ubuntu-0ubuntu120.04 +jit [x86_64-linux]
       user     system      total        real
   4.010000   0.060000   4.070000 (  1.737954)
ledsun@MSI:~/ruby-pi►./run_jruby.sh 10
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
       user     system      total        real
   0.040831   0.000000   0.040831 (  0.040857)
jruby 9.3.7.0 (2.6.8) 2022-08-16 c79ef237e0 OpenJDK 64-Bit Server VM 11.0.16+8-post-Ubuntu-0ubuntu120.04 on 11.0.16+8-post-Ubuntu-0ubuntu120.04 +jit [x86_64-linux]
       user     system      total        real
  15.600000   0.190000  15.790000 ( 12.541831)
ledsun@MSI:~/ruby-pi►./run_jruby.sh 100
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
       user     system      total        real
   0.397269   0.000000   0.397269 (  0.397289)
jruby 9.3.7.0 (2.6.8) 2022-08-16 c79ef237e0 OpenJDK 64-Bit Server VM 11.0.16+8-post-Ubuntu-0ubuntu120.04 on 11.0.16+8-post-Ubuntu-0ubuntu120.04 +jit [x86_64-linux]
       user     system      total        real
 133.670000   0.830000 134.500000 (122.400172)
ledsun@MSI:~/ruby-pi►./run_jruby.sh 1000
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
       user     system      total        real
   4.024466   0.000000   4.024466 (  4.024575)
jruby 9.3.7.0 (2.6.8) 2022-08-16 c79ef237e0 OpenJDK 64-Bit Server VM 11.0.16+8-post-Ubuntu-0ubuntu120.04 on 11.0.16+8-post-Ubuntu-0ubuntu120.04 +jit [x86_64-linux]
       user     system      total        real
 1288.650000   6.590000 1295.240000 (1193.121318)

実行時間は線形に増えます。 ごく普通です。

MJITとYJITはπの計算には効かないらしい

JITが効くまでに時間が掛かるのではないか? - @ledsun blog で、TruffleRubyはJITが効くまでに40秒の実行時間が必要という仮説を立てました。 YJITやMJITではどうなるのでしょうか? 次のスクリプトを実行して計測してみます。

require "bigdecimal"
require "benchmark"

def pi
  prec = 100
  conv = 3
  a = BigDecimal("1")
  b = BigDecimal("1") / BigDecimal("2").sqrt(prec)
  t = BigDecimal("1") / 4
  p = BigDecimal("1")

  for n in 1..conv do
    an = (a + b) / 2
    b = (a * b).sqrt(prec)
    t -= p * (an - a) * (an - a)
    p *= 2
    a = an
  end
end

Benchmark.bm do |x|
  x.report do
    ARGV[0].to_i.times do 
      pi
    end
  end
end
rbenv local 3.1.2
ruby --version
echo "ruby"
ruby pi.rb 10000
echo "ruby --yjit"
ruby --yjit pi.rb 10000
echo "ruby --mjit"
ruby --mjit pi.rb 10000

結果

ledsun@MSI:~/ruby-pi►./run_mjit_yjit.sh
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
ruby
       user     system      total        real
  41.028472   0.010352  41.038824 ( 41.040139)
ruby --yjit
       user     system      total        real
  40.443960   0.000000  40.443960 ( 40.444085)
ruby --mjit
       user     system      total        real
  40.718051   0.007965  41.406107 ( 40.723440)

特に変わりませんでした。 5万回でもかわりません。

ledsun@MSI:~/ruby-pi►./run_mjit_yjit.sh
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
ruby
       user     system      total        real
  81.505591   0.002163  81.507754 ( 81.508523)
ruby --yjit
       user     system      total        real
  81.272216   0.004975  81.277191 ( 81.277804)
ruby --mjit
       user     system      total        real
  82.383351   0.010723  83.412363 ( 82.390819)

πの計算がJITに向かないのかもしれません。 もし、向かないとしたら、なぜ向かないのかは何もわかりません。

追記

このツイートをもらって気がつきました。 πの計算というか、処理のほとんどがBigDecimalなのでJITが効かないみたいです。

Rubyの新しいJIT「MJIT」で早速遊んでみた(翻訳)|TechRacho by BPS株式会社

MJITはRubyYARVバイトコードのブロックの1つを受け取り、基本的にはそれをインラインバージョンのCコードに変換し、これが解釈時に実行されることになります。

とあるように、MJITはCコンパイラコンパイルして高速化していたと記憶しています。 「BigDecimalは元々Cで実装されているので、JITが効かない」はありそうに思えます。

TruffleRubyのスイートスポットはどこ?

JITが効くまでに時間が掛かるのではないか? - @ledsun blog でπを1万回計算したらTruffleRubyがCRubyより速く動きました。 一旦TruffleRubyが速くなったら、計算回数をもっと増やしたらTruffleRubyがもっと速く動くことが期待できます。 50000回計算を試してみました。

ledsun@MSI:~/ruby-pi►./run.sh 50000
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
       user     system      total        real
 209.465692   0.015921 209.481613 (209.481700)
truffleruby 22.2.0, like ruby 3.0.3, GraalVM CE Native [x86_64-linux]
       user     system      total        real
 250.117089  24.163283 274.280372 (213.885274)

CRubyの方が速いです。 念のためもう一度やってみましょう。

ledsun@MSI:~/ruby-pi►./run.sh 50000
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
       user     system      total        real
 201.679176   0.020111 201.699287 (201.700328)
truffleruby 22.2.0, like ruby 3.0.3, GraalVM CE Native [x86_64-linux]
       user     system      total        real
 241.973770  20.865872 262.839642 (210.707100)

やはりCRubyの方が速いです。 TruffleRubyの性能を発揮させるのは、思っていたより難しいです。

なんとなくTruffleRubyには「CRubyのすべての機能はつかえないけど、すくなくともCRubyの同じくらいの速さで動いて、JITが効くと3倍速くなる」みたいなイメージを抱いていました。 そういうものではなさそうです。

TruffleRuby(あるいはjRuby)がCRubyと同じくらいの速さで速さで動いてくれたら、 「GILのない環境で並列化したらCRubyのn倍速くなったぜ!」みたいな例に使えるのかなあ?と期待していました。 いまのところ「CRubyの100倍遅い~同じぐらいの速さ」で動かせています。 時に100倍遅いものをコア数倍速くしてもなあ・・・という感想です。

TruffleRubyが速く動く条件をもうちょっと絞り込みたいです。

JITが効くまでに時間が掛かるのではないか?

いろいろなRubyでπを計算して速さを比べる - @ledsun blog で比較したところTruffle RubyよりCRubyの方がずっと速かったです。 なぜでしょうか? 例えば Ruby 3.0のJITの特性 - @ledsun blog でCRuby 3.0 の MJIT を試した時は実行時間が20秒を超えたあたりから MJIT での高速化が明確に効き始めました。

次のスクリプトを作って試してみました。

スクリプト

require "bigdecimal"
require "benchmark"

def pi
  prec = 100
  conv = 3
  a = BigDecimal("1")
  b = BigDecimal("1") / BigDecimal("2").sqrt(prec)
  t = BigDecimal("1") / 4
  p = BigDecimal("1")

  for n in 1..conv do
    an = (a + b) / 2
    b = (a * b).sqrt(prec)
    t -= p * (an - a) * (an - a)
    p *= 2
    a = an
  end
end

Benchmark.bmbm do |x|
  x.report do
    ARGV[0].to_i.times do 
      pi
    end
  end
end

求めるπの精度は上げずに計算回数を増やします。 計算回数は引数で与えます。 これを次のシェルスクリプトから実行します。

rbenv local 3.1.2
ruby --version
ruby pi.rb $1
rbenv local truffleruby+graalvm-22.2.0
ruby --version
ruby pi.rb $1

結果

ledsun@MSI:~/ruby-pi►./run.sh 1
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
       user     system      total        real
   0.004428   0.000000   0.004428 (  0.004427)
truffleruby 22.2.0, like ruby 3.0.3, GraalVM CE Native [x86_64-linux]
       user     system      total        real
   1.489403   0.011044   1.500447 (  0.455772)
ledsun@MSI:~/ruby-pi►./run.sh 10
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
       user     system      total        real
   0.040624   0.000000   0.040624 (  0.040635)
truffleruby 22.2.0, like ruby 3.0.3, GraalVM CE Native [x86_64-linux]
       user     system      total        real
   2.938930   0.025063   2.963993 (  0.904666)
ledsun@MSI:~/ruby-pi►./run.sh 100
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
       user     system      total        real
   0.389929   0.012847   0.402776 (  0.402843)
truffleruby 22.2.0, like ruby 3.0.3, GraalVM CE Native [x86_64-linux]
       user     system      total        real
   4.807394   0.055102   4.862496 (  1.456071)
ledsun@MSI:~/ruby-pi►./run.sh 1000
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
       user     system      total        real
   4.020903   0.000522   4.021425 (  4.021559)
truffleruby 22.2.0, like ruby 3.0.3, GraalVM CE Native [x86_64-linux]
       user     system      total        real
  19.241751   0.696200  19.937951 (  6.099974)
ledsun@MSI:~/ruby-pi►./run.sh 10000
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
       user     system      total        real
  40.903658   0.010000  40.913658 ( 40.913753)
truffleruby 22.2.0, like ruby 3.0.3, GraalVM CE Native [x86_64-linux]
       user     system      total        real
  76.209975   3.488461  79.698436 ( 40.424835)

計算回数1万回、実行時間40秒でTruffleRubyが勝ちました!

CRubyとTruffleRubyの実行速度の線グラフ

グラフにするとほとんど同じ性能にみえます。 面白いです。

グラフを書くのに参考にしたサイト

追記

よく考えたら両対数グラフにしないと上手く表現できなさそうです。

CRubyとTruffleRubyの実行速度の両対数グラフ

CRubyの実行時間が線形に増えているのに対して、TruffleRubyが何かしら頑張っているのがわかります。 そして10000くらいで頑張りが限界に達していることもわかります。

グラフを書いたときのgnuplotのデータと指示です。

1 0.004427 0.455772
10 0.040635 0.904666
100 0.402843 1.456071
1000 4.021559 6.099974
10000 40.913753 40.424835
gnuplot> plot "test.dat" using 1:2 with lines title "CRuby", "test.dat" using 1:3 with lines title "TruffleRuby"
gnuplot> set logscale x
gnuplot> set logscale y
gnuplot> set yrange [0.001: 41]

いろいろなRubyでπを計算して速さを比べる

計測用のスクリプト

require "bigdecimal"
require "benchmark"

Benchmark.bmbm do |x|
  x.report do
    prec = 100
    conv = 3
    a = BigDecimal("1")
    b = BigDecimal("1") / BigDecimal("2").sqrt(prec)
    t = BigDecimal("1") / 4
    p = BigDecimal("1")
  
    for n in 1..conv do
      an = (a + b) / 2
      b = (a * b).sqrt(prec)
      t -= p * (an - a) * (an - a)
      p *= 2
      a = an
    end
  end
end

jRubyJITの影響を受けるっぽいので、bmbmを使っています。 リハーサル実効時にJITコンパイルされたら、本番時にはJITコンパイル後の速度が測れるだろうという目測です。 本当にそうなのかは確証はありません。

概要

Ruby実装 計算時間(秒)
CRuby 3.1.2 0.004
TruffleRuby 22.0+ GraalVM 0.19
TruffleRuby 22.0 0.26
jRuby 9.3.7 1.29

CRubyが圧倒的に速いです。 Benchmarking CRuby, MJIT, YJIT, JRuby and TruffleRuby · On the Edge of Ruby などで見かけるベンチマークと違います。 あまりにもマイクロなベンチマークなので上手く計測出来ていないのでしょうか? JITが有効になるには、もっとたくさんの実行回数が必要なのでしょうか?

詳細

CRuby 3.1.2

ledsun@MSI:~/ruby-pi►rbenv local 3.1.2
ledsun@MSI:~/ruby-pi►ruby --version
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
ledsun@MSI:~/ruby-pi►ruby pi.rb
Rehearsal ------------------------------------
   0.003965   0.000793   0.004758 (  0.004761)
--------------------------- total: 0.004758sec

       user     system      total        real
   0.004151   0.000000   0.004151 (  0.004136)

jRuby 9.3.7

ledsun@MSI:~/ruby-pi►rbenv local jruby-9.3.7.0
ledsun@MSI:~/ruby-pi►ruby --version
jruby 9.3.7.0 (2.6.8) 2022-08-16 c79ef237e0 OpenJDK 64-Bit Server VM 11.0.16+8-post-Ubuntu-0ubuntu120.04 on 11.0.16+8-post-Ubuntu-0ubuntu120.04 +jit [x86_64-linux]
ledsun@MSI:~/ruby-pi►ruby pi.rb
Rehearsal ------------------------------------
   3.830000   0.040000   3.870000 (  1.706857)
--------------------------- total: 3.870000sec

       user     system      total        real
   1.910000   0.020000   1.930000 (  1.291241)

truffleruby 22.2

ledsun@MSI:~/ruby-pi►rbenv local truffleruby-22.2.0
ledsun@MSI:~/ruby-pi►ruby --version
truffleruby 22.2.0, like ruby 3.0.3, GraalVM CE Native [x86_64-linux]
ledsun@MSI:~/ruby-pi►ruby pi.rb
Rehearsal ------------------------------------
   1.303417   0.046385   1.349802 (  0.421265)
--------------------------- total: 1.349802sec

       user     system      total        real
   0.887849   0.029376   0.917225 (  0.263987)

truffleruby 22.2 + GraalVM

ledsun@MSI:~/ruby-pi►rbenv local truffleruby+graalvm-22.2.0
ledsun@MSI:~/ruby-pi►ruby --version
truffleruby 22.2.0, like ruby 3.0.3, GraalVM CE Native [x86_64-linux]
ledsun@MSI:~/ruby-pi►ruby pi.rb
Rehearsal ------------------------------------
   1.382144   0.022365   1.404509 (  0.421443)
--------------------------- total: 1.404509sec

       user     system      total        real
   0.606478   0.028106   0.634584 (  0.190170)

jRubyでπを計算する

Rubyでπを計算する - @ledsun blog でπを計算するRubyスクリプトが動くことがわかりました。 WSLにjRubyをインストールしてみる - @ledsun blog で設定したjRubyで動かしてみます。

ledsun@MSI:~/ruby-pi►rbenv local jruby-9.3.7.0
ledsun@MSI:~/ruby-pi►ruby pi.rb

まるっきり終わりません。

このスクリプトガウス=ルジャンドルのアルゴリズム - Wikipedia を採用しています。 計算を繰り返す回数を増やすと求められるπの桁数が増えます。 スクリプト中のconv変数が繰返す回数を指定しています。 つまりアルゴリズムを変更せずに計算時間が調整できるパラメーターです。 この値を調整してためしてみます。

jRuby

1

ledsun@MSI:~/ruby-pi►ruby pi.rb
Time: 0.027010284014977515s

2

ledsun@MSI:~/ruby-pi►ruby pi.rb
Time: 0.2614899040199816s

3

ledsun@MSI:~/ruby-pi►ruby pi.rb
Time: 1.905935324029997s

4

ledsun@MSI:~/ruby-pi►ruby pi.rb
Time: 31.895614359993488s

こんなふうに計算時間がふえることあるのでしょうか? アルゴリズム再帰していません。

GCでしょうか? ガタガタになるしても線形に増えそうなものです。 そもそもこの程度のオブジェクト数でGCが走るのでしょうか?

Ruby 3.1.2

Ruby 3.1.2でも試してみます。

ledsun@MSI:~/ruby-pi►rbenv local 3.1.2

1

ledsun@MSI:~/ruby-pi►ruby pi.rb
Time: 0.00016911199782043695s

2

ledsun@MSI:~/ruby-pi►ruby pi.rb
Time: 0.00015715498011559248s

3

ledsun@MSI:~/ruby-pi►ruby pi.rb
Time: 0.004318212973885238s

4

ledsun@MSI:~/ruby-pi►ruby pi.rb
Time: 0.007067304977681488s

5

ledsun@MSI:~/ruby-pi►ruby pi.rb
Time: 0.1696732720010914s

あ、これ求める桁数が増えると線形以上に計算時間が増えるもんなんですね。 単に jRubyRuby 3.1 の200倍遅いのでしょうか?

Rubyでπを計算する

jRubyが並列に動くのか確かめたいです。 CPUバウンドな時間が掛かる処理があるといいはず。 計算に時間が掛かる処理と言えばπの計算です。 BigMath::PIより早く円周率を計算する - Qiitaを参考にして、Rubyでπを計算してみます。

require "bigdecimal"
require "benchmark"

result = Benchmark.realtime do
  prec = 100
  conv = 6
  a = BigDecimal("1")
  b = BigDecimal("1") / BigDecimal("2").sqrt(prec)
  t = BigDecimal("1") / 4
  p = BigDecimal("1")

  for n in 1..conv do
    an = (a + b) / 2
    b = (a * b).sqrt(prec)
    t -= p * (an - a) * (an - a)
    p *= 2
    a = an
  end

  puts (a + b) * (a + b) / (4 * t)
end

puts "Time: #{result}s"

動かしてみます。

ledsun@MSI:~/ruby-pi►ruby pi.rb
Time: 0.19301386800361797s

参考記事より一桁おそいです・・・。 僕の実行環境は 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz なので、2015年の実行環境より遅い確率は低いはずです。 参考にその他の情報も残しておきます。

VPN接続するとWSL内でgitが使えなくて困っていたところを通りすがりの同僚に助けてもらった話

同僚に次のブログを教えてもらいました。

blog.jicoman.info

初めてこの現象に出会ったときは、VPN接続が必要なgitリポジトリが相手でした。 なんとなくそういうもんかな?と思ってスルーしました。 スルーというかMac端末で作業を進めることにしました。

そのうちGitHubリポジトリでも同様の現象が起きることに気がつきました。 GitHubVPN接続が必須でないです。 GitHubを使う時にVPN接続を切って対応していました。

社内の分報で、その手順を書きました。

分報にVPN接続を切ったことを書いた様子

そしたら同僚に補足されて、色々調べて、最初の解決策を見つけてくれました。 分報って良いものですね。

WSLにjRubyをインストールしてみる

Ubuntu にrbenvを使ってrubyとjrubyをインストールする方法 - Qiita を参考にします。

rbenvはインストール済みです。

ledsun@MSI:~[1]►rbenv --version
rbenv 1.2.0-1-g6cc7bff

Javaもインストールされています。

ledsun@MSI:~►java --version
openjdk 11.0.16 2022-07-19
OpenJDK Runtime Environment (build 11.0.16+8-post-Ubuntu-0ubuntu120.04)
OpenJDK 64-Bit Server VM (build 11.0.16+8-post-Ubuntu-0ubuntu120.04, mixed mode, sharing)

インストール可能なjRubyのバージョンを確認します。

ledsun@MSI:~[1]►rbenv install --list
2.6.10
2.7.6
3.0.4
3.1.2
jruby-9.3.4.0
mruby-3.0.0
rbx-5.0
truffleruby-22.0.0.2
truffleruby+graalvm-22.0.0.2

Only latest stable releases for each Ruby implementation are shown.
Use 'rbenv install --list-all / -L' to show all local versions.

なんとなく古い感じがします。

cd .rbenv/plugins/ruby-build/
git pull

もう一度確認します。

ledsun@MSI:~►rbenv install --list
2.6.10
2.7.6
3.0.4
3.1.2
jruby-9.3.7.0
mruby-3.1.0
picoruby-3.0.0
rbx-5.0
truffleruby-22.2.0
truffleruby+graalvm-22.2.0

Only latest stable releases for each Ruby implementation are shown.
Use 'rbenv install --list-all / -L' to show all local versions.

インストールします。

ledsun@MSI:~►rbenv install jruby-9.3.7.0
To follow progress, use 'tail -f /tmp/ruby-build.20220902200227.57472.log' or pass --verbose
Downloading jruby-dist-9.3.7.0-bin.tar.gz...
-> https://dqw8nmjcqpjn7.cloudfront.net/94a7a8b3beeac2253a8876e73adfac6bececb2b54d2ddfa68f245dc81967d0c1
Installing jruby-9.3.7.0...
Installed jruby-9.3.7.0 to /home/ledsun/.rbenv/versions/jruby-9.3.7.0
ledsun@MSI:~[127]►rbenv local jruby-9.3.7.0
ledsun@MSI:~►ruby --version
jruby 9.3.7.0 (2.6.8) 2022-08-16 c79ef237e0 OpenJDK 64-Bit Server VM 11.0.16+8-post-Ubuntu-0ubuntu120.04 on 11.0.16+8-post-Ubuntu-0ubuntu120.04 +jit [x86_64-linux]

こんにちわ!

ledsun@MSI:~►ruby -e 'p "Hello, world!"'
"Hello, world!"

参考

底辺領主の勘違い英雄譚 6

相変わらず自由です。 表紙の見慣れない女性キャラ誰?って思いました。

一見普通だし、とびぬけておかしなことをやっているわけでもなく、 ただただ まともな人間が全く出てこない狂気の世界です。 登場人物の誰もが現代人と同じ価値観ではないので調和した世界になっている、アンパンマン世界みたいです。 いや、ばいきんまんドキンちゃんすらいないので、アンパンマンより徹底しています。

なんでこれで物語が成立しているのかわからない気持ち悪さが、気持ちいいです。

おっさん、勇者と魔王を拾う

なろう小説のコミカライズです。 作画の方がやけに漫画を描くことになれているのが印象的です。 那州雪絵さんのようです。 絵柄はちょっとやわらかいです。

省略の仕方に迷いがないというか、何を書けば場面を描けるのかわかっている感じがします。 ベテランなのかというと、検索する限り商業漫画デビュー作のようです。 白川祐 - pixivはあるので、同人歴がながくて作風が確立してる方なのかもしれません。

掲載媒体はWebコミック おっさん、勇者と魔王を拾う@COMIC 第21話 ②|コロナEX です。 なるほど、最近はなろう小説と同人漫画家さんを組み合わせて商業漫画化するのが多そうです*1

*1:僕が好き好んでこのゾーンから読む漫画を拾ってきているのは、その通りです。

ソウルハッカーズ

ソウルハッカーズをはじめました。

soul-hackers.jp

このツイートみてから気がついたんですけど、キャラクターデザイン、三輪士郎さんだったんですね。

三輪士郎さんの描くキャラクターが好きなんです。

ジャケ買いしました。 もう20年前ですね。

眼帯キャラがでてくるとニヤニヤしちゃいます。