Performance is often an important criterion for measuring code. We often use some magic methods in our daily coding. Will these magic methods provided by PHP affect the performance of our program? Is it necessary to reduce the use of magic methods? This article will use test comparison to understand the impact of magic methods on performance.
Doubt
Is the magic method really poor in performance?
Is there still a problem with the performance of using magic methods in PHP7?
How should we use magic methods reasonably?
Plan
Faced with my doubts, my plan is:
Statistical comparison of the time difference between script execution using the magic method and not using the magic method
Continuously execute the script n times under PHP5.6.26-1
Statistics on the average/minimum/maximum value of the execution time
Continuously execute the script n times under PHP7.0.12-2
Statistical average/minimum/maximum execution time
Test
__construct
First of all, let’s take a look at the experiment of the constructor __construct. The PHP script is as follows:
<?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 does not use the magic method. The data is as follows, in microseconds μ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 uses the magic method data as follows, the unit is microsecond μ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 does not use the magic method data as follows, the unit microsecond μ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 uses the magic method data as follows , unit microsecond μ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
We can see from the above data:
The average execution time of a script using __construct as the constructor is Faster than using the class name as the constructor, about 5 to 6 microseconds faster, both in php5.6 and php7.0.
__call
Next, let’s take a look at the __call experiment. The php script is as follows:
<?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";
PHP5.6 does not use the magic method. The data is as follows, the unit is microsecond μ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
PHP5.6 uses the magic method. The data is as follows, the unit is microsecond μ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 The data without magic method is as follows, the unit is microsecond μ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 uses the magic method data as follows, the unit is microsecond μ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
We can see from the above data:
The average execution time of scripts using __call is slower than not using it, about 2 microseconds slower, whether in php5.6 or php7.0.
__callStatic
Next, let’s take a look at the __callStatic experiment. The php script is as follows:
<?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";
PHP5.6 does not use the magic method. The data is as follows, the unit is microsecond μs
// 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
PHP5.6 uses the magic method. The data is as follows, the unit is microsecond μ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
PHP7.0 The data without magic method is as follows, the unit is microsecond μ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 uses the magic method data as follows, the unit is microsecond μ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
We can see from the above data:
In php5.6, the average execution time of scripts using __callStatic is slower than not using it, about 3 microseconds; in php7.0, the average execution time of scripts using __callStatic is roughly equal to not using it. __callStatic;
##__set
Next, let’s take a look at the __set experiment, php The script is as follows:<?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
##__getNext, let’s take a look at the __get experiment. The php script is as follows:
<?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 does not use the magic method. The data is as follows, the unit is microsecond μs
// 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 uses the magic method. The data is as follows, the unit is microsecond μ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 The data without magic method is as follows, the unit is microsecond μ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 uses the magic method data as follows, the unit is microsecond μ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
We can see from the above data:
The average execution time of scripts using __get in php5.6 is roughly equal to that without __get; the average execution time of scripts using __get in php7.0 is slower than not using it, probably slower. 3 microseconds.
ConclusionHere we mainly tested __construct(), __call(), __callStatic() , __get(), __set() are five commonly used magic functions that can be replaced by other implementations. After passing the above test, I will come back to answer my doubts
#Is the performance of the magic method really poor?
Answer: In addition to using __construct, the time of using other magic methods here is roughly within 10 microseconds.
#Is there still a problem with the performance of magic methods in PHP7?
Answer: The difference between using and not using magic methods in PHP7 is almost the same as in PHP5.6.
How should we use magic methods reasonably?
Answer: Through the entire test, we can see that the difference in execution time between not using the magic method is roughly within 10 microseconds, so if the magic method can save our development costs and optimize our With the code structure, we should be able to consider sacrificing less than 10 microseconds. __construct is meant to be fast, so there should be no objection to using __construct.
The above is the detailed content of Performance exploration of commonly used magic methods in PHP. For more information, please follow other related articles on the PHP Chinese website!