👀

【Ruby】まとめでよく見る処理速度の計測方法・見方

2022/01/26に公開

記事を書くにあたり、Rubyの処理速度の計測方法分からなかったので調べてみました。

標準ライブラリのbenchmark

Rubyにはbenchmarkライブラリという名前の通りベンチマークを取るための標準ライブラリがあるらしい。

基本的にBenchmarkモジュールのbmメソッドで良さそう。
benchmarkライブラリ
bmメソッド

使い方

コード

require 'benchmark'

n = 50000
Benchmark.bm do |x|
  x.report { for i in 1..n; a = "1"; end }
  x.report { n.times do   ; a = "1"; end }
  x.report { 1.upto(n) do ; a = "1"; end }
end
#=>
#     user     system      total        real
# 1.033333   0.016667   1.016667 (  0.492106)
# 1.483333   0.000000   1.483333 (  0.694605)
# 1.516667   0.000000   1.516667 (  0.711077)

どう見るの?

結論から言うと、目的によってuser と total のどちらかを見れば良さそう。
それぞれざっくりこんな感じらしいです。

user

ユーザー CPU 時間
ユーザープログラムの実行に費やした CPU 時間。この場合、Ruby スクリプトを実行すべく Ruby 処理系が働いたぶんの CPU 時間のこと。

system

システム CPU 時間
OS はファイルの読み書きなどの基本的な機能を「システムコール」という形で提供しているが、プログラムがそれを呼び出しその実行に費やした CPU 時間をこう呼ぶらしい。

total

userとsystemの和

real

処理の開始から終了までの現実の経過時間
Timeクラスを使用した場合と同じなので、待機時間が含まれたりネットワークの影響も受けてしまうため、見る必要はない。

結果を見やすくする

bmメソッドは第一引数でラベルの幅を設定できる。
reportで見やすいようにラベルを設定しつつ、bmメソッドの引数にラベルの最大文字数+スペース分を入れると見やすそう。

# 設定略
Benchmark.bm(7) do |x|
  x.report("for:")   { for i in 1..n; a = "1"; end }
  x.report("times:") { n.times do   ; a = "1"; end }
  x.report("upto:")  { 1.upto(n) do ; a = "1"; end }
end

#=>
#              user     system      total        real
# for:     1.050000   0.000000   1.050000 (  0.503462)
# times:   1.533333   0.016667   1.550000 (  0.735473)
# upto:    1.500000   0.016667   1.516667 (  0.711239)



第二引数以降はブロックが配列を返す場合のラベルを設定できる。
合計や、平均を出したい場合に便利

# 設定略
Benchmark.bm(7, ">total:", ">avg:") do |x|
  tf = x.report("for:")   { for i in 1..n; a = "1"; end }
  tt = x.report("times:") { n.times do   ; a = "1"; end }
  tu = x.report("upto:")  { 1.upto(n) do ; a = "1"; end }
  [tf + tt + tu, (tf + tt + tu) / 3]
end

#=>
#               user     system      total        real
# for:      0.001467   0.004727   0.006194 (  0.006193)
# times:    0.003814   0.000000   0.003814 (  0.003814)
# upto:     0.003855   0.000003   0.003858 (  0.003859)
# >total:   0.009136   0.004730   0.013866 (  0.013867)
# >avg:     0.003045   0.001577   0.004622 (  0.004622)



参考記事

Discussion