您好,登錄后才能下訂單哦!
這篇文章主要講解了“PHP中高精度計時器HRTime擴展”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“PHP中高精度計時器HRTime擴展”吧!
不知道大家還記得在學校的時候體育測試時老師帶的秒表嗎?當槍聲想起時,我們開始跑步,這時秒表啟動,當我們跑過終點后,老師會按下按扭記錄我們的成績,這就是一個典型的定時器的應用。今天我們要學習的內容其實就是和這個體育測驗的秒表類似的一個功能擴展,它就是 PHP 的 HRTime 擴展。
首先我們要了解一下什么叫做系統的時鐘節拍。當 Linux 系統啟動之后,會同時啟動一個時鐘節拍器,以納秒為單位進行計時,而我們的 HRTime 擴展的真實名稱是 高精度時間 擴展。也就是說,它正是基于操作系統的時鐘節拍器,能夠以納秒為單位進行計時。
1秒=1000毫秒=1000000微妙=1000000000納秒,這是秒、毫秒、微秒和納秒的關系,看出來它的精度有多高了吧。1秒等于10億納秒,這樣我們就可以獲得一個非常精確的時間間隔計數。
HRTime 擴展直接在 PECL 進行下載安裝就可以了,和其他的普通擴展沒有什么區別。
我們先來看看如何獲取操作系統的時鐘節拍,也就是這個 Ticks 。關于它的內容在學習操作系統的時候相信已經有不少的同學接觸過了,這里我們看看使用 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
接下來的這三個函數就是 HRTime 擴展中的 PerformanceCounter 對象的靜態函數了。PerformanceCounter 對象的意思是性能計數器,getFrequency() 表示的是計時器頻率(以滴答Ticks/秒為單位),可以看出,它返回的就是納秒單位,也就是 10億 。getTicks() 返回的是當前的時鐘節拍時間,可以看出它和 hrtime(true) 函數的結果是一樣的,都是返回的系統啟動后的時鐘節拍時間。getTicksSince() 方法則是根據指定的納秒數返回時間間隔,類似于 date_diff() 的感覺,其實就像我們的 time() - time() 這樣的操作。通過這個方法就可以獲得一段代碼兩次運行的時間間隔,而且是以納秒為單位哦。
接下來就是我們文章的重點內容了,也就是定時器功能的實現。上面已經說過,使用 getTickSince() 其實也能做到監控一段代碼的運行時間間隔,不過下面將學習到的內容將更加強大。
$c = new HRTime\StopWatch; $c->start(); for ($i = 0; $i < 1024*1024; $i++); echo 'isRunning: ', $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() 則是獲得最后一次間隔的時鐘節拍信息。既然有【最后一次】這四個字,那么也就說明這個對象是可以多次調用的來分段計時的。并且,它還是可以將多段不同的計時進行匯總,獲得全部的時間間隔信息的。
// 不在計時范圍內 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
在這段代碼中,我們在兩段計時測試代碼中插入了一個循環測試代碼,它不會計入到計時數據中。接著,我們重新 start() 開始一個新的計時,在最后,我們通過 getElapsedTime() 和 getElapsedTicks() 兩個方法獲得總的計時時間,可以看出上面的 6929888 加上這次的 7154010 結果正好是 14083898 。中間的那一段沒有在定時器中的循環代碼沒有計入到總的計時時間中。
是不是很有意思,它的作用真的和我們的體育老師所用的那個秒表一模一樣,老師們的秒表也都是可以按多次記錄第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中高精度計時器HRTime擴展這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。