La performance est souvent un critère important pour mesurer le code. Nous utilisons souvent des méthodes magiques dans notre codage quotidien. Ces méthodes magiques fournies par PHP affecteront-elles les performances de notre programme ? Est-il nécessaire de réduire le recours aux méthodes magiques ? Cet article utilisera la comparaison de tests pour comprendre l'impact des méthodes magiques sur les performances.
Doute
La méthode magique est-elle vraiment peu performante ?
Y a-t-il toujours un problème avec les performances d'utilisation des méthodes magiques en PHP7 ?
Comment devrions-nous utiliser les méthodes magiques de manière raisonnable ?
Planifier
Face à mes doutes, mon plan est le suivant :
Comparer statistiquement le décalage horaire entre l'exécution du script en utilisant la méthode magique et sans utiliser la méthode magique
Exécuter le script n fois en continu sous PHP5.6.26-1
Statistiques sur le temps d'exécution moyen/minimum/maximum
Exécuter le script n fois en continu sous PHP7.0.12-2
Temps d'exécution statistique moyen/minimum/maximum
Test
__construct
Tout d'abord, jetons un œil à l'expérience de la fonction constructeur __construct. Le script PHP est le suivant :
<?php /** * 魔术方法性能探索 * * 构造函数 * * @author TIGERB <https://github.com/TIGERB> */ require('./function.php'); if (!isset($argv[1])) { die('error: variable is_use_magic is empty'); } $is_use_magic = $argv[1]; /** * 构造函数使用类名 */ class ClassOne { public function classOne() { # code... } } /** * 构造函数使用魔术函数__construct */ class ClassTwo { public function __construct() { # code... } } $a = getmicrotime(); if ($is_use_magic === 'no_magic') { new ClassOne(); }else { new ClassTwo(); } $b = getmicrotime(); echo ($b-$a) . "\n";
PHP5.6 n'utilise pas la méthode magique. Les données sont les suivantes, dans. microsecondes μs
// PHP5.6中连续调用脚本10000次 sh test 10000 no_magic php5 construct // 运行数据统计脚本 sh analysis ./logs/__construct_no_magic_php5.log 10000 // 结果 avg: 34μs max: 483μs min: 26μs
PHP5.6 utilise la méthode magique et les données sont les suivantes, l'unité est la microseconde μs
// PHP5.6中连续调用脚本10000次 sh test 10000 magic php5 construct // 运行数据统计脚本 sh analysis ./logs/__construct_magic_php5.log 10000 // 结果 avg: 28μs max: 896μs min: 20μs
PHP7.0 n'utilise pas la méthode magique et le les données sont les suivantes, l'unité est la microseconde μs
// PHP7.0中连续调用脚本10000次 sh test 10000 no_magic php construct // 运行数据统计脚本 sh analysis ./logs/__construct_no_magic_php.log 10000 // 结果 avg: 19μs max: 819μs min: 13μs
PHP7.0 utilise les données de la méthode magique comme suit, l'unité est la microseconde μs
// PHP7.0中连续调用脚本10000次 sh test 10000 magic php construct // 运行数据统计脚本 sh analysis ./logs/__construct_magic_php.log 10000 // 结果 avg: 14μs max: 157μs min: 10μs
À partir des données ci-dessus, nous pouvons voir :
Utiliser __construct comme Le temps d'exécution moyen du script constructeur est plus rapide que l'utilisation du nom de classe comme constructeur, environ 5 à 6 microsecondes plus rapide, que ce soit en php5. 6 ou php7.0.
__call
Ensuite, jetons un coup d'œil à l'expérience __call. Le script php est le suivant. suit :
<?php /** * 魔术方法性能探索 * * 构造函数 * * @author TIGERB <https://github.com/TIGERB> */ require('./function.php'); if (!isset($argv[1])) { die('error: variable is_use_magic is empty'); } $is_use_magic = $argv[1]; /** * 构造函数使用类名 */ class ClassOne { public function __construct() { # code... } public function test() { # code... } } /** * 构造函数使用魔术函数__construct */ class ClassTwo { public function __construct() { # code... } public function __call($method, $argus) { # code... } } $a = getmicrotime(); if ($is_use_magic === 'no_magic') { $instance = new ClassOne(); $instance->test(); }else { $instance = new ClassTwo(); $instance->test(); } $b = getmicrotime(); echo ($b-$a) . "\n";
Les données de PHP5.6 sans méthode magique sont les suivantes, l'unité est la microseconde μs
// PHP5.6中连续调用脚本10000次 sh test 10000 no_magic php5 call // 运行数据统计脚本 sh analysis ./logs/__call_no_magic_php5.log 10000 // 结果 avg: 27μs max: 206μs min: 20μs
Les données de PHP5.6 utilisant la méthode magique sont les suivantes , l'unité est la microseconde μs
// PHP5.6中连续调用脚本10000次 sh test 10000 magic php5 call // 运行数据统计脚本 sh analysis ./logs/__call_magic_php5.log 10000 // 结果 avg: 29μs max: 392μs min: 22μs
PHP7.0 n'utilise pas la méthode magique. Les données sont les suivantes, l'unité est la microseconde μs
// PHP7.0中连续调用脚本10000次 sh test 10000 no_magic php call // 运行数据统计脚本 sh analysis ./logs/__call_no_magic_php.log 10000 // 结果 avg: 16μs max: 256μs min: 10μs
PHP7.0 utilise la microseconde μs
// PHP7.0中连续调用脚本10000次 sh test 10000 magic php call // 运行数据统计脚本 sh analysis ./logs/__call_magic_php.log 10000 // 结果 avg: 18μs max: 2459μs min: 11μs
PHP7.0 utilise la méthode magique. méthode magique. Les données sont les suivantes, l'unité est la microseconde μs
Par ce qui précède, nous pouvons voir à partir des données :
Le temps d'exécution moyen des scripts utilisant __call est plus lent que je ne l'utilise pas, environ 2 microsecondes plus lentement, que ce soit en php5.6 ou en php7.0.
__callStatic
<?php /** * 魔术方法性能探索 * * 静态重载函数 * * @author TIGERB <https://github.com/TIGERB> */ require('./function.php'); if (!isset($argv[1])) { die('error: variable is_use_magic is empty'); } $is_use_magic = $argv[1]; /** * 存在test静态方法 */ class ClassOne { public function __construct() { # code... } public static function test() { # code... } } /** * 使用重载实现test */ class ClassTwo { public function __construct() { # code... } public static function __callStatic($method, $argus) { # code... } } $a = getmicrotime(); if ($is_use_magic === 'no_magic') { ClassOne::test(); }else { ClassTwo::test(); } $b = getmicrotime(); echo ($b-$a) . "\n";
Ensuite, jetons un coup d'œil à l'expérience __callStatic Le script php est le suivant. suit :
// PHP5.6中连续调用脚本10000次 sh test 10000 no_magic php5 callStatic // 运行数据统计脚本 sh analysis ./logs/__callStatic_no_magic_php5.log 10000 // 结果 avg: 25μs max: 129μs min: 19μs
Les données de PHP5.6 sans méthode magique sont les suivantes, l'unité est la microseconde μs
// PHP5.6中连续调用脚本10000次 sh test 10000 magic php5 callStatic // 运行数据统计脚本 sh analysis ./logs/__callStatic_magic_php5.log 10000 // 结果 avg: 28μs max: 580μs min: 20μs
Les données de PHP5.6 utilisant la méthode magique sont les suivantes , l'unité est la microseconde μs
// PHP7.0中连续调用脚本10000次 sh test 10000 no_magic php callStatic // 运行数据统计脚本 sh analysis ./logs/__callStatic_no_magic_php.log 10000 // 结果 avg: 14μs max: 130μs min: 9μs
PHP7.0 n'utilise pas la méthode magique. Les données sont les suivantes, l'unité est la microseconde μs
// PHP7.0中连续调用脚本10000次 sh test 10000 magic php callStatic // 运行数据统计脚本 sh analysis ./logs/__callStatic_magic_php.log 10000 // 结果 avg: 14μs max: 159μs min: 10μs
PHP7.0 utilise la microseconde μs
PHP7.0 utilise la méthode magique. méthode magique. Les données sont les suivantes, l'unité est la microseconde μsLe temps d'exécution moyen des scripts utilisant __callStatic en php5. 6 est plus lent que sans, environ 3 microsecondes ; scripts utilisant __callStatic dans php7.0 Le temps d'exécution moyen devrait être à peu près égal à celui sans __callStatic ; 🎜>__set
Ensuite, jetons un coup d'œil à l'expérience __set Le script PHP est le suivant :<?php /** * 魔术方法性能探索 * * 设置私有属性__set * * @author TIGERB <https://github.com/TIGERB> */ require('./function.php'); if (!isset($argv[1])) { die('error: variable is_use_magic is empty'); } $is_use_magic = $argv[1]; /** * 实现公共方法设置私有属性 */ class ClassOne { /** * 私有属性 * * @var string */ private $someVariable = 'private'; public function __construct() { # code... } public function setSomeVariable($value = '') { $this->someVariable = $value; } } /** * 使用_set设置私有属性 */ class ClassTwo { /** * 私有属性 * * @var string */ private $someVariable = 'private'; public function __construct() { # code... } public function __set($name = '', $value = '') { $this->$name = $value; } } $a = getmicrotime(); if ($is_use_magic === 'no_magic') { $instance = new ClassOne(); $instance->setSomeVariable('public'); }else { $instance = new ClassTwo(); $instance->someVariable = 'public'; } $b = getmicrotime(); echo ($b-$a) . "\n";
// PHP5.6中连续调用脚本10000次 sh test 10000 no_magic php5 set // 运行数据统计脚本 sh analysis ./logs/__set_no_magic_php5.log 10000 // 结果 avg: 31μs max: 110μs min: 24μs
// PHP5.6中连续调用脚本10000次 sh test 10000 magic php5 set // 运行数据统计脚本 sh analysis ./logs/__set_magic_php5.log 10000 // 结果 avg: 33μs max: 138μs min: 25μs
// PHP7.0中连续调用脚本10000次 sh test 10000 no_magic php set // 运行数据统计脚本 sh analysis ./logs/__set_no_magic_php.log 10000 // 结果 avg: 15μs max: 441μs min: 11μs
// PHP7.0中连续调用脚本10000次 sh test 10000 magic php set // 运行数据统计脚本 sh analysis ./logs/__set_magic_php.log 10000 // 结果 avg: 17μs max: 120μs min: 11μs
__get
Ensuite, jetons un coup d'œil à l'expérience __get. Le script php est le suivant. suit :<?php /** * 魔术方法性能探索 * * 读取私有属性__get * * @author TIGERB <https://github.com/TIGERB> */ require('./function.php'); if (!isset($argv[1])) { die('error: variable is_use_magic is empty'); } $is_use_magic = $argv[1]; /** * 实现公共方法获取私有属性 */ class ClassOne { /** * 私有属性 * * @var string */ private $someVariable = 'private'; public function __construct() { # code... } public function getSomeVariable() { return $this->someVariable; } } /** * 使用_get获取私有属性 */ class ClassTwo { /** * 私有属性 * * @var string */ private $someVariable = 'private'; public function __construct() { # code... } public function __get($name = '') { return $this->$name; } } $a = getmicrotime(); if ($is_use_magic === 'no_magic') { $instance = new ClassOne(); $instance->getSomeVariable(); }else { $instance = new ClassTwo(); $instance->someVariable; } $b = getmicrotime(); echo ($b-$a) . "\n";
// PHP5.6中连续调用脚本10000次 sh test 10000 no_magic php5 get // 运行数据统计脚本 sh analysis ./logs/__get_no_magic_php5.log 10000 // 结果 avg: 28μs max: 590μs min: 20μs
// PHP5.6中连续调用脚本10000次 sh test 10000 magic php5 get // 运行数据统计脚本 sh analysis ./logs/__get_magic_php5.log 10000 // 结果 avg: 28μs max: 211μs min: 22μs
// PHP7.0中连续调用脚本10000次 sh test 10000 no_magic php get // 运行数据统计脚本 sh analysis ./logs/__get_no_magic_php.log 10000 // 结果 avg: 16μs max: 295μs min: 10μs
// PHP7.0中连续调用脚本10000次 sh test 10000 magic php get // 运行数据统计脚本 sh analysis ./logs/__get_magic_php.log 10000 // 结果 avg: 19μs max: 525μs min: 12μs
Par ce qui précède, nous pouvons voir à partir des données :
Le temps d'exécution moyen des scripts utilisant __get en php5. 6 est à peu près égal au temps d'exécution moyen des scripts qui n'utilisent pas __get ; le temps d'exécution moyen des scripts utilisant __get dans php7.0 Le temps est plus lent que lorsqu'il n'est pas utilisé, environ 3 microsecondes plus lent.
Conclusion
Ici, nous avons principalement testé __construct(), __call(), __callStatic() , __get(), __set() sont cinq fonctions magiques couramment utilisées qui peuvent être remplacées par d'autres implémentations. Après avoir réussi le test ci-dessus, je reviendrai répondre à mes questions
La méthode magique est-elle vraiment peu performante ?
R : En plus d'utiliser __construct, le temps d'utilisation d'autres méthodes magiques ici est d'environ 10 microsecondes.
Y a-t-il toujours un problème avec les performances des méthodes magiques en PHP7 ?
R : La différence entre utiliser et ne pas utiliser les méthodes magiques en PHP7 est presque la même qu'en PHP5.6.
R : Tout au long du test, nous pouvons voir que la différence de temps d'exécution entre ne pas utiliser la méthode magique est d'environ 10 microsecondes, donc si la méthode magique peut économiser nos coûts de développement et optimiser notre Avec la structure du code, nous il faudrait pouvoir envisager de sacrifier moins de 10 microsecondes. __construct est censé être rapide, il ne devrait donc y avoir aucune objection à utiliser __construct.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!