PHPの高精度タイマーHRTime拡張機能の詳細説明

藏色散人
リリース: 2023-04-10 10:52:01
転載
3663 人が閲覧しました

学校の体育のテスト中に先生が持ってきたストップウォッチをまだ覚えているかどうかわかりません。銃声が鳴り響くと走り始め、ストップウォッチが動き、ゴールラインを通過したら先生がボタンを押して結果を記録するという典型的なタイマーアプリです。今日学習するのは、実はこのスポーツテストのストップウォッチに似た機能拡張で、PHP の HRTime 拡張機能です。

クロック ビート

まず、システムのクロック ビートとは何かを理解する必要があります。 Linux システムが起動すると、クロック メトロノームが同時に起動され、ナノ秒単位でタイミングを測定します。HRTime 拡張機能の本当の名前は、High-Precision Time 拡張機能です。つまり、ナノ秒単位でタイミングを計測できるオペレーティングシステムをベースとした時計メトロノームです。

1秒 = 1000ミリ秒 = 1000000マイクロ秒 = 1000000000ナノ秒 これは、秒、ミリ秒、マイクロ秒、ナノ秒の関係であり、その精度の高さがわかります。 1 秒は 10 億ナノ秒に等しいため、時間間隔を非常に正確にカウントできます。

HRTime 拡張機能は PECL から直接ダウンロードしてインストールでき、他の通常の拡張機能と何ら変わりません。

システム クロック ティック情報の取得 Ticks

まず、オペレーティング システムのクロック ティック (この Ticks) を取得する方法を見てみましょう。その内容については、OSを学ぶ際に多くの学生が触れたことがあると思いますが、ここではHRTime拡張機能を利用した入手方法を見ていきます。

print_r(hrtime());
// Array
// (
//     [0] => 3758
//     [1] => 407409171
// )

echo hrtime(true), PHP_EOL;
// 3758407428932
ログイン後にコピー

hrtime() この関数は、PHP7 以降のデフォルトの PHP 環境に統合されました。 HRTime 拡張機能を使用する必要はありません。この関数はパラメータなしで配列を返します。0 番目の項目はシステムが起動してからの秒数、1 番目の項目は対応するナノ秒カウントです。このパラメータを true に設定すると、秒とナノ秒を連結した実際のナノ秒タイムスタンプが直接返されます。

echo HRTime\PerformanceCounter::getFrequency(), PHP_EOL; // 1000000000
echo HRTime\PerformanceCounter::getTicks(), PHP_EOL; // 3758428256236
echo HRTime\PerformanceCounter::getTicksSince(1212), PHP_EOL; // 3758428257494

$a = HRTime\PerformanceCounter::getTicks();
echo HRTime\PerformanceCounter::getTicksSince($a), PHP_EOL; // 412
ログイン後にコピー

次の 3 つの関数は、HRTime 拡張機能の PerformanceCounter オブジェクトの静的関数です。 PerformanceCounter オブジェクトはパフォーマンス カウンターを意味し、getFrequency() はタイマー頻度 (ティック/秒) を表し、ナノ秒単位 (10 億) を返していることがわかります。 getTicks() は現在のクロック ティック タイムを返します。その結果は、システムの起動後に返されるクロック ティック タイムである hrtime(true) 関数と同じであることがわかります。 getTicksSince() メソッドは、指定されたナノ秒数に基づいて時間間隔を返します。これは date_diff() に似ており、実際、 time() - time() 操作に似ています。このメソッドを通じて、コードの 2 回の実行間の時間間隔を取得できます。単位はナノ秒です。

タイマー関数

次のステップは、この記事の焦点であるタイマー関数の実装です。上で述べたように、getTickSince() を使用すると、コードの一部の実行時間間隔を実際に監視できますが、以下で学ぶことはより強力です。

$c = new HRTime\StopWatch;

$c->start();
for ($i = 0; $i < 1024*1024; $i++);
echo &#39;isRunning: &#39;, $c->isRunning(), PHP_EOL; // isRunning: 1
$c->stop();

echo 'Time NS: ', $c->getLastElapsedTime(HRTime\Unit::NANOSECOND), PHP_EOL;
echo 'Time US: ', $c->getLastElapsedTime(HRTime\Unit::MICROSECOND), PHP_EOL;
echo 'Time MS: ', $c->getLastElapsedTime(HRTime\Unit::MILLISECOND), PHP_EOL;
echo 'Time S: ', $c->getLastElapsedTime(HRTime\Unit::SECOND), PHP_EOL;
// Time NS: 6929888
// Time US: 6929.888
// Time MS: 6.929888
// Time S: 0.006929888

echo 'Ticks: ',$c->getLastElapsedTicks(), PHP_EOL;
// Ticks: 6929888

echo 'isRunning: ',$c->isRunning(), PHP_EOL;
//
ログイン後にコピー

StopWatch オブジェクトをインスタンス化し、その start() メソッドを呼び出してタイマーを開始する必要があります。 StopWatch の英語自体の意味はタイマーの意味であるため、このオブジェクトはタイマーの操作を提供するために特別に設計されています。 isRunning() メソッドを使用すると、現在のタイマーが実行中かどうかを判断できます。実際には、現在のタイマーが start() メソッドの後にあるかどうかを判断するためです。start() と stop( の範囲内にない場合は、 )、その場合は false が返されます。テスト コードでは、1024*1024 の空のループを実行し、stop() メソッドを使用してタイマーを終了します。

コードからわかるように、getLastElapsedTime() は、上記のコードの start() と stop() の間の時間間隔情報を取得するためのもので、パラメータは秒とミリ秒で指定できます。 、ナノ秒。このメソッド自体の意味は、最後の間隔の実行時間を取得することです。 getLastElapsedTicks() は、最後の間隔のクロック ティック情報を取得します。 [前回]という単語が4つあるので、このオブジェクトは分割されたタイミングで複数回呼び出すことができることを意味します。さらに、複数の異なるタイミングを要約して、すべての時間間隔情報を取得することもできます。

// 不在计时范围内
for ($i = 0; $i < 1024*1024; $i++);

$c->start();
for ($i = 0; $i < 1024*1024; $i++);
$c->stop();

echo 'Time NS: ', $c->getLastElapsedTime(HRTime\Unit::NANOSECOND), PHP_EOL;
echo 'Time US: ', $c->getLastElapsedTime(HRTime\Unit::MICROSECOND), PHP_EOL;
echo 'Time MS: ', $c->getLastElapsedTime(HRTime\Unit::MILLISECOND), PHP_EOL;
echo 'Time S: ', $c->getLastElapsedTime(HRTime\Unit::SECOND), PHP_EOL;
// Time NS: 7154010
// Time US: 7154.01
// Time MS: 7.15401
// Time S: 0.00715401

echo 'All Time NS: ', $c->getElapsedTime(HRTime\Unit::NANOSECOND), PHP_EOL;
echo 'All Time US: ', $c->getElapsedTime(HRTime\Unit::MICROSECOND), PHP_EOL;
echo 'All Time MS: ', $c->getElapsedTime(HRTime\Unit::MILLISECOND), PHP_EOL;
echo 'All Time S: ', $c->getElapsedTime(HRTime\Unit::SECOND), PHP_EOL;
// All Time NS: 14083898
// All Time US: 14083.898
// All Time MS: 14.083898
// All Time S: 0.014083898

echo 'All Ticks: ', $c->getElapsedTicks(), PHP_EOL;
// All Ticks: 14083898
ログイン後にコピー

このコードでは、2 つのタイミング テスト コードの間にループ テスト コードを挿入しましたが、これはタイミング データにはカウントされません。次に、 restart() して新しいタイミングを開始します。最後に、 getElapsedTime() と getElapsedTicks() を通じて合計タイミング時間を取得します。上記の 6929888 に今回の 7154010 を加えると、正確に 14083898 になることがわかります。タイマーに含まれないループ コードの中間セクションは、合計計時時間には含まれません。

推奨学習: 「PHP ビデオ チュートリアル

总结

是不是很有意思,它的作用真的和我们的体育老师所用的那个秒表一模一样,老师们的秒表也都是可以按多次记录第1名到最后1名的全部跑步成绩,并且最后还有一个总的时间,而在代码中我们也是完全相似的操作。这个扩展对于精细的性能调试非常有用,而且也能够针对一些需要这种高精度时间差的业务进行相关的开发。

测试代码:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202010/source/3.学习PHP中的高精度计时器HRTime扩展.php
参考文档:
https://www.php.net/manual/zh/book.hrtime.php
ログイン後にコピー

以上がPHPの高精度タイマーHRTime拡張機能の詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
php
ソース:segmentfault.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート