パフォーマンスの測定
Benchmark モジュールです。
「パフォーマンスの測定」はCoddyKit上の無料Ruby Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはRuby Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Ruby Academyコースには全4レッスンが含まれています。
なぜ計測するのか
計測せずに最適化するのは、当てずっぽうで作業することと同じです。Rubyの標準ライブラリにあるBenchmarkモジュールを使うと、コードの実行時間を正確に計測できます。
- 変更する前に遅い部分を見つけます
- 実装を客観的に比較します
- 早すぎる最適化を避けます
require 'benchmark'
time = Benchmark.realtime do
1_000_000.times { |i| i * 2 }
end
puts "Took #{time.round(4)}s"Benchmark.measure
Benchmark.measureは、ユーザー時間、システム時間、実時間のレポートを返します。
- ユーザー時間はコードが消費したCPU時間です
- 実時間は壁時計で測った経過時間です
require 'benchmark'
result = Benchmark.measure do
500_000.times { |i| i.to_s }
end
puts resultBenchmark.bm
Benchmark.bmは複数のブロックを実行し、表形式でラベルを付けます。
- 整列用にラベル幅を指定します
- 各
x.reportが1行になります
require 'benchmark'
Benchmark.bm(10) do |x|
x.report('to_s:') { 100_000.times { |i| i.to_s } }
x.report('inspect:') { 100_000.times { |i| i.inspect } }
endBenchmark.bmbm
Benchmark.bmbmは、キャッシュとGCを温めるために、まずリハーサルを実行します。これにより、より公平な値を得られます。
- 最初の実行結果は破棄されます
- 2回目の実行が実際の計測になります
require 'benchmark'
Benchmark.bmbm do |x|
x.report('sum:') { (1..100_000).sum }
x.report('reduce:') { (1..100_000).reduce(:+) }
end簡易計測のrealtime
Benchmark.realtimeは、壁時計による経過秒数だけを浮動小数点数で返します。
- 1つのブロックを計測する最も簡単な方法です
- その場で行う簡単な確認に適しています
require 'benchmark'
elapsed = Benchmark.realtime do
arr = Array.new(100_000) { rand }
arr.sort
end
puts "Sorted in #{elapsed.round(4)}s"単調クロック
システムクロックの変更に影響されない正確な計測には、単調クロックとともにProcess.clock_gettimeを使います。
- NTPによる調整の影響を受けません
- 組み込み機能の中で最も正確な選択肢です
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
200_000.times { |i| i * i }
finish = Process.clock_gettime(Process::CLOCK_MONOTONIC)
puts "Elapsed: #{(finish - start).round(4)}s"2つのアプローチを比較する
ベンチマークは、複数の選択肢を比較するときに力を発揮します。両方を同じ負荷で実行してください。
- 計測できるように入力サイズを十分大きくします
- 繰り返し実行してノイズを減らします
require 'benchmark'
arr = (1..100_000).to_a
Benchmark.bm(8) do |x|
x.report('map:') { arr.map { |n| n * 2 } }
x.report('each:') { r = []; arr.each { |n| r << n * 2 } }
endマイクロベンチマークに注意する
小さすぎるベンチマークは誤解を招くことがあります。
- JITやキャッシュが実際のワークロードを反映しない場合があります
- 計測の途中でGCが実行されることがあります
- 現実的なデータサイズを計測します
require 'benchmark'
# Too small to be meaningful
t = Benchmark.realtime { 10.times { |i| i + 1 } }
puts "Misleadingly tiny: #{t}s"1秒あたりの反復回数
多くの場合、知りたいのはスループット、つまり1秒あたりに何回処理できるかです。benchmark-ips gemでこれを計測できますが、手動でおおよその値を求めることもできます。
- 一定の時間内で反復回数を数えます
- ipsが高いほど高速です
deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + 0.2
count = 0
while Process.clock_gettime(Process::CLOCK_MONOTONIC) < deadline
count += 1
'hello'.upcase
end
puts "Iterations in 0.2s: #{count}"GCを制御する
ガベージコレクターによって結果が偏ることがあります。GCを一時的に無効にすると、より安定した値を得られます。
- 前に
GC.disableを、後にGC.enableを実行します - メモリが増え続けないよう、慎重に使います
require 'benchmark'
GC.disable
t = Benchmark.realtime { 100_000.times { |i| i.to_s } }
GC.enable
puts "Without GC: #{t.round(4)}s"複数回の実行を平均する
ベンチマークを何度か実行して平均を取ると、ばらつきをならせます。
- 必要に応じて最も遅い外れ値を除外します
- 安定性のために中央値を報告します
require 'benchmark'
times = 3.times.map do
Benchmark.realtime { (1..50_000).map { |n| n * n } }
end
avg = times.sum / times.size
puts "Average: #{avg.round(4)}s"理解度チェック
ベンチマークについての知識を確認しましょう。
まとめ
パフォーマンスの計測方法を学びました。
Benchmarkモジュールでコードの実行時間を正確に計測できますrealtime、measure、bm、bmbmはそれぞれ異なる用途に適しています- 正確な計測には単調クロックを使います
- 誤解を招くマイクロベンチマークを避け、GCの影響を考慮します
- 複数回の実行を平均してノイズを減らします
次は専用のプロファイリングツールを使います。
よくある質問
「パフォーマンスの測定」レッスンは無料ですか?
はい。「パフォーマンスの測定」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Ruby Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Ruby Academyコースには全4レッスンが含まれています。
「パフォーマンスの測定」で何を学びますか?
Benchmark モジュールです。 ブラウザで直接実行するハンズオンコードでRuby Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Ruby Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのRuby Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「パフォーマンスの測定」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このRuby Academyレッスンでコードを書いて実行できますか?
はい。すべてのRuby Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- パフォーマンスの測定
- プロファイリングツール
- メモリ最適化
- よくあるボトルネック