【PHP】処理時間の計測でmicrotimeは古い?高精度なhrtimeの使い方

【PHP】処理時間の計測でmicrotimeは古い?高精度なhrtimeの使い方 PHP

結論から言います。
PHPで処理時間を計測するなら、microtime関数ではなく hrtime関数 を使うのが現在の正解です。

ネット上の古い記事を「脳死」でコピペしてmicrotime(true)を使っている人をよく見かけますが、正直、その計測結果は信頼性に欠けます。

もちろん、大まかな秒数を知るだけなら十分かもしれません。
しかし、ミリ秒・ナノ秒単位のパフォーマンスチューニングが求められる現場では、そのわずかな「時刻のズレ」が致命的な判断ミスを招きます。

エンジニアとして、単に動くコードではなく、環境の変化に左右されない「精度の高い計測」を行う流儀を身につけてください。

【執筆者の簡易プロフィール】
kazu 執筆者:kazu
  • 38歳男性、既婚
  • Webエンジニア
  • 新卒でSESに入社し、Web系企業に常駐、その後Web系スタートアップに転職
  • 主な使用言語はRuby、PHP、JavaScript、HTML/CSS
  • モットーは「人に厳しく、自分にはもっと厳しく」

なぜ多くのサイトで紹介されているmicrotimeは危ういのか

多くの入門サイトでは、計測の開始と終了に microtime(true) を使い、その差分を出す方法が紹介されています。

しかし、この microtime は「システム時刻(Unixタイム)」に基づいています。
ここに落とし穴があります。

外部要因による「時刻跳び」の影響を受けるから

サーバーは常に正確な時間を刻んでいるわけではありません。
NTP(Network Time Protocol)による時刻同期が走った際、時計がわずかに進んだり、あるいは戻ったりすることがあります。

もし計測中に時刻同期が発生したらどうなるでしょうか?

処理時間はマイナスになったり、異常に長い数値になったりします。

これでは、正確なボトルネックの特定など不可能です。

ダメな例:時刻同期に弱い古い計測コード

// 多くのサイトで見かける、正直おすすめしない書き方
$start = microtime(true);

// 何らかの重い処理
usleep(100000);

$end = microtime(true);
$executionTime = $end - $start;

echo "実行時間: " . $executionTime . " 秒";

このコードは「今、何時何分何秒か」の差を計算しているに過ぎません。

パフォーマンス計測において重要なのは「純粋にどれだけの時間が経過したか」であって、カレンダー上の時刻ではありません。

高精度な計測を実現するhrtime関数の最短ルート

PHP 7.3から導入された hrtime()(High Resolution Time) は、高精度な「モノトニッククロック(単調増加時計)」を利用します。

これはシステム時刻の影響を一切受けず、OSが起動してからの経過時間をナノ秒単位で返すため、計測中に時計が調整されても数値が狂いません。

実務でそのまま使えるhrtimeの標準実装

// 1. 計測開始(ナノ秒を数値として取得)
$start = hrtime(true);

// --- 計測したい処理ここから ---
for ($i = 0; $i < 1000000; $i++) {
$tmp = $i * 2;
}
// --- 計測したい処理ここまで ---

// 2. 計測終了
$end = hrtime(true);

// 3. 差分を計算(ナノ秒からミリ秒へ変換)
$nanoTime = $end - $start;
$milliTime = $nanoTime / 1e+6; // 1,000,000で割る

echo "実行時間: " . $milliTime . " ms";

このコードのポイントは、hrtime(true) と引数に true を渡している点です。
これにより、ナノ秒が int または float(環境による)で返ってくるため、単純な引き算だけで済みます。

ナノ秒単位(10億分の1秒)での計測ができるため、マイクロ秒(100万分の1秒)までしか追えない microtime よりも圧倒的に高精度です。

ボトルネックを特定するためにメモリ使用量もセットで見る

処理時間が長い原因が「アルゴリズムの複雑さ」にあるのか、それとも「メモリの使いすぎによるGC(ガベージコレクション)の発生」にあるのかを切り分ける必要があります。

時間だけを測るのは片手落ちです。
私は必ずメモリ使用量もセットで確認します。

効率厨が現場で実践する複合計測パターン

$start_time = hrtime(true);
$start_memory = memory_get_usage();

// 計測対象の処理
$data = range(1, 100000);

$end_time = hrtime(true);
$end_memory = memory_get_usage();

// 結果の出力
printf("Time: %f ms\n", ($end_time - $start_time) / 1e+6);
printf("Memory: %d KB\n", ($end_memory - $start_memory) / 1024);

このように memory_get_usage() を併用することで、「この処理でどれだけメモリを消費したか」が可視化されます。

「時間は短いがメモリを大量に食うコード」は、同時アクセスが増えた瞬間にサーバーを落とす「爆弾」になります。

時間とメモリ。
この2軸でコードを評価するのが、プロのエンジニアの規律です。

まとめ:正確な計測が良質なコードを生む

PHPの時間計測を、単なる「目安」で終わらせないでください。

カレンダー時刻に依存する microtime は、実務の計測には不向き。
PHP 7.3以降なら hrtime を使い、ナノ秒単位のモノトニッククロックで測る。
時間だけでなく memory_get_usage でメモリ負荷も同時に追跡する。

「なんとなく遅い気がする」という曖昧な感覚を捨て、確かな数値に基づいて改善を行う。
その一歩が、無駄のない、美しく効率的なシステムを創り上げることにつながります。

以上です。

コメント

タイトルとURLをコピーしました