Ruby Benchmarkでパフォーマンス測定をする

はじめに

お久しぶりです!ソフトウェアエンジニアの飯塚(@hiizkk)です。前回はRidgepoleでスキーマ管理をするブログを書きました。
最近はブルーロックにハマっています。運(計画的偶発性理論)や挑戦的集中などの(たぶんエンジニアも大好きな)概念が登場しますし、めちゃめちゃ熱い作風で自分みたいにサッカーに興味がなくても楽しめる作品だと思うので興味ある方はぜひ手にとってみてください!

Ridgepoleでスキーマ管理をする

今回は書く内容をとても迷いましたが、SREの観点からパフォーマンスチューニングに興味がある人が多いと思いますし、個人的に数学とアルゴリズムを勉強しているので、Rubyで処理時間を計測できるBenchmarkというライブラリについて記事を書いていこうと思います。


Benchmarkとは?

https://docs.ruby-lang.org/ja/latest/class/Benchmark.html

普段開発する中で、「このバッチの実行時間遅いな…」など感じる機会があると思います。そんな時に役立つのがBenchmarkです。基本形は以下の通りになります。


実際に使ってみる

これでアルゴリズムの入門書でよく出てくる年齢当てゲームの線形探索と二分探索を計測してみましょう。

  • 結果

1,000,000の20だともはや線形も二分も変わらないですね。ちなみに年齢的にありえませんが、my_ageを999,999にすると以下の通りです。

計算量 O(N)(線形探索)は計算回数が多い分だけ実行時間がかかりますし、O(log N)(二分探索)はターゲットがどこにあっても計算速度は大きく変動しないということが分かりますね。


出力結果の項目について

ここで、いくつか項目が出ているようです。

Ruby3.4リファレンスマニュアル ただ屋ぁのブログ さんの説明を借りるとそれぞれ以下を意味するそうです。

  • user: user CPU time、Rubyプログラム自体のコード実行に費やされた時間
  • system: system CPU time 、OSのコード(システムコール)が実行された時間
  • total: total CPU time、user+system
  • real: 実経過時間

線形探索と二分探索のコードはほとんどuser CPU timeが長いみたいです。なのでRubyプログラムがメインで動いていると判断してよさそうですね。systemについては scivolaさんの記事 によりますと以下のように、Rubyの class File を使ったりすると増加すると思いましたので試してみました。

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

  • 結果

確かに線形探索と二分探索のコードよりもsystem の使用時間が長いようですね。使う機能によってここまで違いが出ていることが分かります。


まとめ

RubyのBenchmarkの簡単な解説と使ってみた記事を書いてみました。メジャーなmoduleなので調べればもっと詳しくて素晴らしい記事もたくさん出てきますが、自分でコード書いて試したりすることで、新たな発見ができることもありますね。個人的には以下の3つが大きな学びでした。

  • CPUの実行時間の種類(user, system)を知ることができた
  • Rubyのどんなコードでsystem CPUが使われているのかがわかった
  • アルゴリズムの特徴を計算量や数値で捉えることができた

今後もBenchmarkを使ってパフォーマンスを意識して実装していきたいと思います。


注釈

※ただし、何回か実行してみると大きく変動がありました。

bmbmメソッドのリファレンス によると、とあるので、GC(Garbage Collection)の影響でブレに繋がっているようですね。上記リンクのbmbmメソッドはGCの影響をなくすためにあるらしいですが、実際に試しても普通にブレたのでまあ当てにならない気がします。様々な記事によると複数回実行した結果の平均で測定するようです。

ベンチマークの結果は GC の影響によって歪められてしまうことがあります。実際にはこのメソッドを使用しても、GC などの影響を分離することは保証されません。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール