Je me demande si vous vous souvenez encore du chronomètre que le professeur a apporté lors du test d'éducation physique à l'école ? Lorsque le coup de feu retentissait, nous commencions à courir et le chronomètre démarrait. Lorsque nous passions la ligne d'arrivée, l'enseignant appuyait sur le bouton pour enregistrer nos résultats. Il s'agit d'une application de chronométrage typique. Ce que nous allons apprendre aujourd'hui est en fait une extension fonctionnelle similaire au chronomètre de ce test sportif. Il s'agit de l'extension HRTime de PHP.
Clock Beat
Tout d'abord, nous devons comprendre quel est le battement d'horloge du système. Lorsque le système Linux démarre, un métronome d'horloge sera démarré en même temps pour mesurer le timing en nanosecondes, et le vrai nom de notre extension HRTime est l'extension de temps de haute précision. En d’autres termes, il s’agit d’un métronome d’horloge basé sur le système d’exploitation qui peut mesurer le timing en nanosecondes.
1 seconde = 1000 millisecondes = 1000000 microsecondes = 1000000000 nanosecondes C'est la relation entre les secondes, les millisecondes, les microsecondes et les nanosecondes. Vous pouvez voir à quel point elle est précise. 1 seconde équivaut à 1 milliard de nanosecondes, nous pouvons donc obtenir un décompte très précis des intervalles de temps.
L'extension HRTime peut être téléchargée et installée directement depuis PECL. Elle n'est pas différente des autres extensions ordinaires.
Obtenir les informations sur les ticks de l'horloge système Ticks
Voyons d'abord comment obtenir le tick de l'horloge du système d'exploitation, qui est ce Ticks. Concernant son contenu, je pense que de nombreux étudiants l'ont déjà contacté lors de l'apprentissage des systèmes d'exploitation. Nous voyons ici comment l'obtenir en utilisant l'extension HRTime.
print_r(hrtime()); // Array // ( // [0] => 3758 // [1] => 407409171 // ) echo hrtime(true), PHP_EOL; // 3758407428932
hrtime() Cette fonction a été intégrée dans l'environnement PHP par défaut après PHP7. Il ne nécessite pas l’utilisation de l’extension HRTime. Cette fonction renvoie un tableau sans paramètres. Le 0ème élément est le nombre de secondes depuis le démarrage du système et le 1er élément est le nombre de nanosecondes correspondant. Si vous définissez son paramètre sur true, il renverra directement l'horodatage réel en nanosecondes concaténé avec les secondes et les nanosecondes.
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
Les trois fonctions suivantes sont les fonctions statiques de l'objet PerformanceCounter dans l'extension HRTime. L'objet PerformanceCounter signifie un compteur de performances et getFrequency() représente la fréquence du minuteur (en ticks/seconde). On peut voir qu'il renvoie l'unité nanoseconde, qui est de 1 milliard. getTicks() renvoie l'heure actuelle du tic-tac de l'horloge. On peut voir que le résultat est le même que celui de la fonction hrtime(true), qui est l'heure du tic-tac de l'horloge renvoyée après le démarrage du système. La méthode getTicksSince() renvoie l'intervalle de temps basé sur le nombre spécifié de nanosecondes, ce qui est similaire à date_diff(). En fait, c'est comme notre opération time() - time(). Grâce à cette méthode, vous pouvez obtenir l'intervalle de temps entre deux exécutions d'un morceau de code, et l'unité est la nanoseconde.
Fonction minuterie
La prochaine étape est au centre de notre article, qui est la mise en œuvre de la fonction minuterie. Comme mentionné ci-dessus, l'utilisation de getTickSince() peut en fait surveiller l'intervalle de temps d'exécution d'un morceau de code, mais ce que vous apprendrez ci-dessous sera plus puissant.
$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; //
Nous devons instancier un objet StopWatch puis appeler sa méthode start() pour qu'un timer démarre. La signification anglaise de StopWatch lui-même est la signification de minuterie, cet objet est donc spécialement conçu pour servir au fonctionnement de la minuterie. Grâce à la méthode isRunning(), nous pouvons déterminer si le minuteur actuel est en cours d'exécution. En fait, il s'agit de déterminer si le minuteur actuel est après une méthode start() si elle n'est pas dans le cadre de start() et stop(. ), alors il retournera false. Dans le code de test, nous exécutons une boucle vide de 1024*1024, puis utilisons la méthode stop() pour mettre fin au timer.
Comme le montre le code, getLastElapsedTime() consiste à obtenir les informations sur l'intervalle de temps entre start() et stop() de notre code ci-dessus. Ses paramètres peuvent être spécifiés en secondes, millisecondes, microsecondes, nanosecondes. Le but de cette méthode elle-même est d'obtenir le temps d'exécution du dernier intervalle. getLastElapsedTicks() obtient les informations de tick d'horloge du dernier intervalle. Puisqu'il y a quatre mots [dernière fois], cela signifie que cet objet peut être appelé plusieurs fois pour un timing segmenté. De plus, il peut toujours résumer plusieurs timings différents pour obtenir toutes les informations sur les intervalles de temps.
// 不在计时范围内 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
Dans ce code, nous avons inséré un code de test de boucle entre les deux codes de test de timing, qui ne sera pas compté dans les données de timing. Ensuite, nous restart() pour démarrer un nouveau timing. À la fin, nous obtenons le temps de timing total via getElapsedTime() et getElapsedTicks(). On peut voir que les 6929888 ci-dessus plus cette fois 7154010 donnent exactement 14083898 . La partie centrale du code de boucle qui n'est pas dans le chronomètre n'est pas incluse dans le temps de chronométrage total.
Apprentissage recommandé : "Tutoriel vidéo 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