亚洲最大看欧美片,亚洲图揄拍自拍另类图片,欧美精品v国产精品v呦,日本在线精品视频免费

  • 站長資訊網(wǎng)
    最全最豐富的資訊網(wǎng)站

    詳解PHP中高精度計時器HRTime擴(kuò)展

    不知道大家還記得在學(xué)校的時候體育測試時老師帶的秒表嗎?當(dāng)槍聲想起時,我們開始跑步,這時秒表啟動,當(dāng)我們跑過終點后,老師會按下按扭記錄我們的成績,這就是一個典型的定時器的應(yīng)用。今天我們要學(xué)習(xí)的內(nèi)容其實就是和這個體育測驗的秒表類似的一個功能擴(kuò)展,它就是 PHP 的 HRTime 擴(kuò)展。

    時鐘節(jié)拍

    首先我們要了解一下什么叫做系統(tǒng)的時鐘節(jié)拍。當(dāng) Linux 系統(tǒng)啟動之后,會同時啟動一個時鐘節(jié)拍器,以納秒為單位進(jìn)行計時,而我們的 HRTime 擴(kuò)展的真實名稱是 高精度時間 擴(kuò)展。也就是說,它正是基于操作系統(tǒng)的時鐘節(jié)拍器,能夠以納秒為單位進(jìn)行計時。

    1秒=1000毫秒=1000000微妙=1000000000納秒,這是秒、毫秒、微秒和納秒的關(guān)系,看出來它的精度有多高了吧。1秒等于10億納秒,這樣我們就可以獲得一個非常精確的時間間隔計數(shù)。

    HRTime 擴(kuò)展直接在 PECL 進(jìn)行下載安裝就可以了,和其他的普通擴(kuò)展沒有什么區(qū)別。

    獲取系統(tǒng)時鐘節(jié)拍信息 Ticks

    我們先來看看如何獲取操作系統(tǒng)的時鐘節(jié)拍,也就是這個 Ticks 。關(guān)于它的內(nèi)容在學(xué)習(xí)操作系統(tǒng)的時候相信已經(jīng)有不少的同學(xué)接觸過了,這里我們看看使用 HRTime 擴(kuò)展如何獲取。

    print_r(hrtime()); // Array // ( //     [0] => 3758 //     [1] => 407409171 // )  echo hrtime(true), PHP_EOL; // 3758407428932

    hrtime() 這個函數(shù)在 PHP7 之后已經(jīng)集成在默認(rèn) PHP 環(huán)境中了。它不需要 HRTime 擴(kuò)展就可以使用。這個函數(shù)在沒有參數(shù)的情況下返回的是一個數(shù)組,第 0 項是系統(tǒng)啟動到現(xiàn)在的秒數(shù),第 1 項就是對應(yīng)的納秒計數(shù)。如果給它的參數(shù)設(shè)置一個 true 的話,它將直接返回將秒和納秒拼接起來的實際納秒時間戳。

    echo HRTimePerformanceCounter::getFrequency(), PHP_EOL; // 1000000000 echo HRTimePerformanceCounter::getTicks(), PHP_EOL; // 3758428256236 echo HRTimePerformanceCounter::getTicksSince(1212), PHP_EOL; // 3758428257494  $a = HRTimePerformanceCounter::getTicks(); echo HRTimePerformanceCounter::getTicksSince($a), PHP_EOL; // 412

    接下來的這三個函數(shù)就是 HRTime 擴(kuò)展中的 PerformanceCounter 對象的靜態(tài)函數(shù)了。PerformanceCounter 對象的意思是性能計數(shù)器,getFrequency() 表示的是計時器頻率(以滴答Ticks/秒為單位),可以看出,它返回的就是納秒單位,也就是 10億 。getTicks() 返回的是當(dāng)前的時鐘節(jié)拍時間,可以看出它和 hrtime(true) 函數(shù)的結(jié)果是一樣的,都是返回的系統(tǒng)啟動后的時鐘節(jié)拍時間。getTicksSince() 方法則是根據(jù)指定的納秒數(shù)返回時間間隔,類似于 date_diff() 的感覺,其實就像我們的 time() – time() 這樣的操作。通過這個方法就可以獲得一段代碼兩次運行的時間間隔,而且是以納秒為單位哦。

    定時器功能

    接下來就是我們文章的重點內(nèi)容了,也就是定時器功能的實現(xiàn)。上面已經(jīng)說過,使用 getTickSince() 其實也能做到監(jiān)控一段代碼的運行時間間隔,不過下面將學(xué)習(xí)到的內(nèi)容將更加強(qiáng)大。

    $c = new HRTimeStopWatch;  $c->start(); for ($i = 0; $i < 1024*1024; $i++); echo 'isRunning: ', $c->isRunning(), PHP_EOL; // isRunning: 1 $c->stop();  echo 'Time NS: ', $c->getLastElapsedTime(HRTimeUnit::NANOSECOND), PHP_EOL; echo 'Time US: ', $c->getLastElapsedTime(HRTimeUnit::MICROSECOND), PHP_EOL; echo 'Time MS: ', $c->getLastElapsedTime(HRTimeUnit::MILLISECOND), PHP_EOL; echo 'Time S: ', $c->getLastElapsedTime(HRTimeUnit::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 對象,然后調(diào)用它的 start() 方法,這樣一個定時器就啟動了。StopWatch 的英文涵義本身就是定時器的意思,所以這個對象是專門為定時器的操作所服務(wù)的。通過 isRunning() 方法我們可以判斷當(dāng)前定時器是否運行,其實就是判斷當(dāng)前是否是在一個 start() 方法之后,如果不在 start() 和 stop() 范圍中,那么它將返回 false 。在測試代碼中,我們運行一個 1024*1024 的空循環(huán),然后再使用 stop() 方法結(jié)束定時器。

    從代碼中可以看出,getLastElapsedTime() 就是獲得我們上面的那個 start() 到 stop() 之間的代碼運行耗時的時間間隔信息,它的參數(shù)可以指定為秒、毫秒、微秒、納秒。本身這個方法的意思就是獲取獲取最后一個間隔的運行時間。getLastElapsedTicks() 則是獲得最后一次間隔的時鐘節(jié)拍信息。既然有【最后一次】這四個字,那么也就說明這個對象是可以多次調(diào)用的來分段計時的。并且,它還是可以將多段不同的計時進(jìn)行匯總,獲得全部的時間間隔信息的。

    // 不在計時范圍內(nèi) for ($i = 0; $i < 1024*1024; $i++);  $c->start(); for ($i = 0; $i < 1024*1024; $i++); $c->stop();  echo 'Time NS: ', $c->getLastElapsedTime(HRTimeUnit::NANOSECOND), PHP_EOL; echo 'Time US: ', $c->getLastElapsedTime(HRTimeUnit::MICROSECOND), PHP_EOL; echo 'Time MS: ', $c->getLastElapsedTime(HRTimeUnit::MILLISECOND), PHP_EOL; echo 'Time S: ', $c->getLastElapsedTime(HRTimeUnit::SECOND), PHP_EOL; // Time NS: 7154010 // Time US: 7154.01 // Time MS: 7.15401 // Time S: 0.00715401  echo 'All Time NS: ', $c->getElapsedTime(HRTimeUnit::NANOSECOND), PHP_EOL; echo 'All Time US: ', $c->getElapsedTime(HRTimeUnit::MICROSECOND), PHP_EOL; echo 'All Time MS: ', $c->getElapsedTime(HRTimeUnit::MILLISECOND), PHP_EOL; echo 'All Time S: ', $c->getElapsedTime(HRTimeUnit::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

    在這段代碼中,我們在兩段計時測試代碼中插入了一個循環(huán)測試代碼,它不會計入到計時數(shù)據(jù)中。接著,我們重新 start() 開始一個新的計時,在最后,我們通過 getElapsedTime() 和 getElapsedTicks() 兩個方法獲得總的計時時間,可以看出上面的 6929888 加上這次的 7154010 結(jié)果正好是 14083898 。中間的那一段沒有在定時器中的循環(huán)代碼沒有計入到總的計時時間中。

    推薦學(xué)習(xí):《PHP視頻教程》

    總結(jié)

    是不是很有意思,它的作用真的和我們的體育老師所用的那個秒表一模一樣,老師們的秒表也都是可以按多次記錄第1名到最后1名的全部跑步成績,并且最后還有一個總的時間,而在代碼中我們也是完全相似的操作。這個擴(kuò)展對于精細(xì)的性能調(diào)試非常有用,而且也能夠針對一些需要這種高精度時間差的業(yè)務(wù)進(jìn)行相關(guān)的開發(fā)。

    測試代碼: https://github.com/zhangyue0503/dev-blog/blob/master/php/202010/source/3.學(xué)習(xí)PHP中的高精度計時器HRTime擴(kuò)展.php 參考文檔: https://www.php.net/manual/zh/book.hrtime.php

    贊(0)
    分享到: 更多 (0)
    網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號