學習PHP中的高精度計時器HRTime擴充套件

2021-10-20 18:38:55 字數 4520 閱讀 9335

不知道大家還記得在學校的時候體育測試時老師帶的秒錶嗎?當槍聲想起時,我們開始跑步,這時秒錶啟動,當我們跑過終點後,老師會按下按扭記錄我們的成績,這就是乙個典型的定時器的應用。今天我們要學習的內容其實就是和這個體育測驗的秒錶類似的乙個功能擴充套件,它就是 php 的 hrtime 擴充套件。

首先我們要了解一下什麼叫做系統的時鐘節拍。當 linux 系統啟動之後,會同時啟動乙個時鐘節拍器,以納秒為單位進行計時,而我們的 hrtime 擴充套件的真實名稱是 高精度時間 擴充套件。也就是說,它正是基於作業系統的時鐘節拍器,能夠以納秒為單位進行計時。

1秒=1000毫秒=1000000微妙=1000000000納秒,這是秒、毫秒、微秒和納秒的關係,看出來它的精度有多高了吧。1秒等於10億納秒,這樣我們就可以獲得乙個非常精確的時間間隔計數。

我們先來看看如何獲取作業系統的時鐘節拍,也就是這個 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名的全部跑步成績,並且最後還有乙個總的時間,而在**中我們也是完全相似的操作。這個擴充套件對於精細的效能除錯非常有用,而且也能夠針對一些需要這種高精度時間差的業務進行相關的開發。

測試**:

學習php中的高精度計時器hrtime擴充套件.php

關於高精度計時器

關於高精度計時器 一 毫秒級精度 1 net system.environment.tickcount 獲取系統啟動後經過的毫秒數,包裝了gettickcount 2 winapi gettickcount dllimport kernel32 static extern uint gettickc...

Windows Linux高精度計時器 C

linux windows 系統高精度計時器 ifndef lx timer h define lx timer h ifdef win32 include elif linux include endif class lxtimer endif include lxtimer.h ifdef wi...

高精度納秒計時器

ktimer.h windows graphics programming win32 gdi and directdraw?feng yuan publisher prentice hall ptr first edition december 01,2000 高精度納秒計時器,最後修改 2008...