새 형제 Laruence가 "마술 방법"을 사용하는 것이 권장되지 않는다고 언급한 것을 기억한 적이 있습니다. 그 이후로 마법 방법이 포함될 때마다 블로거들은 무의식적으로 그것에 대해 생각할 것입니다. 이것이 좋은 사진입니까? 지난 2년간 일하느라 바빠서 새로운 지식을 배우느라 이 고비에 대해 깊이 있게 탐구하지 못하고 올해는 블로거들이 깊이 있게 연구해야 할 해였습니다. , 이제 이 문제는 해결되어야 합니다. 먼저 Bird Brother Laruence가 자신의 블로그에서 언급한 내용을 살펴보겠습니다.
최적화 제안은 사람들이 코드를 남용하고 부주의하게 사용하는 것을 방지하기 위한 제안입니다. 코드를 작성할 때 무엇이 느리고 무엇이 빠른지 알 수 있습니다. 매직 메소드에 대한 불필요한 호출, 이것이 바로 이번 최적화 제안이 추구하는 효과입니다
매직 메소드의 성능이 정말 형편없나요?
PHP7에서 매직 메소드를 사용하는 성능에 여전히 문제가 있나요?
마술방법을 어떻게 합리적으로 사용해야 할까요?
의심에 직면하여 내 계획은 다음과 같습니다.
매직 메소드를 사용할 때와 사용하지 않을 때의 스크립트 실행 시간 차이를 통계적으로 비교합니다.
PHP5.6.26-1에서 스크립트를 n번 연속 실행합니다.
통계적 실행 시간 평균값/최소값/최대값
PHP7.0.12-2에서 스크립트를 n번 연속 실행합니다
실행 시간의 평균/최소값/최대값을 통계합니다
현재 제 개인 능력은 한계가 있어서 더 있으면 좋은 해결방법이나 제안사항 있으면 알려주시면 감사하겠습니다 ㅎㅎ~
우선 생성자 __construct의 실험을 살펴보겠습니다. .php 스크립트는 다음과 같습니다.
<?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不使用魔术方法数据如下,单位微秒μm// PHP5.6中连续调用脚本10000次sh test 10000 no_magic php5 construct// 运行数据统计脚本sh analysis ./logs/__construct_no_magic_php5.log 10000// 结果avg: 34μm max: 483μm min: 26μm
PHP5.6에서는 다음과 같이 매직 메소드 데이터를 사용하며, 단위는 마이크로초 μm입니다.
// PHP5.6에서는 스크립트를 10,000번 연속 호출합니다.
sh test 10000 magic php5 construct// 运行数据统计脚本sh analysis ./logs/__construct_magic_php5.log 10000// 结果avg: 28μmmax: 896μmmin: 20μm
PHP7.0은 그렇지 않습니다. 매직 메소드를 사용합니다. 단위는 마이크로초 μm
// PHP7.0中连续调用脚本10000次sh test 10000 no_magic php construct// 运行数据统计脚本sh analysis ./logs/__construct_no_magic_php.log 10000// 结果avg: 19μmmax: 819μmmin: 13μm
PHP7.0은 매직 메소드를 사용합니다. 데이터는 마이크로초 μm입니다.
// PHP7에서는 10,000번 연속 호출됩니다. .0
sh test 10000 magic php construct// 运行数据统计脚本sh analysis ./logs/__construct_magic_php.log 10000// 结果avg: 14μmmax: 157μmmin: 10μm
위 데이터에서 다음을 볼 수 있습니다.
__construct를 생성자로 사용하는 스크립트의 평균 실행 시간은 클래스 이름을 생성자로 사용하는 것보다 빠릅니다. 아마도 php5.6에서 둘 다 5~6 마이크로초 더 빠를 것입니다. 그리고 php7.0.
다음으로 __call 실험을 살펴보겠습니다. PHP 스크립트는 다음과 같습니다.
<?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不使用魔术方法数据如下,单位微秒μm// PHP5.6中连续调用脚本10000次sh test 10000 no_magic php5 call// 运行数据统计脚本sh analysis ./logs/__call_no_magic_php5.log 10000// 结果avg: 27μm max: 206μm min: 20μm
PHP5.6에서는 마이크로초 단위로
// PHP5.6中连续调用脚本10000次sh test 10000 magic php5 call// 运行数据统计脚本sh analysis ./logs/__call_magic_php5.log 10000// 结果avg: 29μmmax: 392μmmin: 22μm
PHP7.0을 사용합니다. 데이터는 단위는 다음과 같습니다. 마이크로초 μm
// PHP7.0中连续调用脚本10000次sh test 10000 no_magic php call// 运行数据统计脚本sh analysis ./logs/__call_no_magic_php.log 10000// 结果avg: 16μmmax: 256μmmin: 10μm
PHP7.0은 다음과 같은 매직 방법 데이터를 사용합니다. 단위는 마이크로초 μm
// PHP7.0中连续调用脚本10000次sh test 10000 magic php call// 运行数据统计脚本sh analysis ./logs/__call_magic_php.log 10000// 结果avg: 18μmmax: 2459μmmin: 11μm
위 데이터에서 확인할 수 있습니다. __call을 사용하는 스크립트의 평균 실행 시간은 이를 사용하지 않는 것보다 느리며, php5.6과 php7.0 모두에서 대략 2마이크로초 더 느립니다.
__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"; PHP5.6不使用魔术方法数据如下,单位微秒μm// PHP5.6中连续调用脚本10000次sh test 10000 no_magic php5 callStatic// 运行数据统计脚本sh analysis ./logs/__callStatic_no_magic_php5.log 10000// 结果avg: 25μm max: 129μm min: 19μm
PHP5.6은 매직 메서드를 사용합니다. 단위는 마이크로초
// PHP5.6中连续调用脚本10000次sh test 10000 magic php5 callStatic// 运行数据统计脚本sh analysis ./logs/__callStatic_magic_php5.log 10000// 结果avg: 28μmmax: 580μmmin: 20μm
PHP7.0입니다. 데이터는 단위는 다음과 같습니다. 마이크로초 μm
// PHP7.0中连续调用脚本10000次sh test 10000 no_magic php callStatic// 运行数据统计脚本sh analysis ./logs/__callStatic_no_magic_php.log 10000// 结果avg: 14μmmax: 130μmmin: 9μm
PHP7.0은 다음과 같은 매직 방법 데이터를 사용하며, 단위는 마이크로초 μm
// PHP7.0中连续调用脚本10000次sh test 10000 magic php callStatic// 运行数据统计脚本sh analysis ./logs/__callStatic_magic_php.log 10000// 结果avg: 14μmmax: 159μmmin: 10μm
위의 데이터를 통해 알 수 있습니다. PHP5.6에서 __callStatic을 사용하는 스크립트의 평균 실행 시간은 더 느립니다. 사용하지 않으면 php7.0에서 약 3마이크로초 더 느려집니다. __callStatic을 사용하는 스크립트의 평균 실행 시간은 __callStatic을 사용하지 않는 것과 대략 같습니다.
__set다음으로 __set 실험을 살펴보겠습니다. php 스크립트는 다음과 같습니다.<?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不使用魔术方法数据如下,单位微秒μm// PHP5.6中连续调用脚本10000次sh test 10000 no_magic php5 set// 运行数据统计脚本sh analysis ./logs/__set_no_magic_php5.log 10000// 结果avg: 31μm max: 110μm min: 24μm
// PHP5.6中连续调用脚本10000次 sh test 10000 magic php5 set// 运行数据统计脚本sh analysis ./logs/__set_magic_php5.log 10000// 结果avg: 33μmmax: 138μmmin: 25μm PHP7.0不使用魔术方法数据如下,单位微秒μm// PHP7.0中连续调用脚本10000次sh test 10000 no_magic php set// 运行数据统计脚本sh analysis ./logs/__set_no_magic_php.log 10000// 结果avg: 15μmmax: 441μmmin: 11μm PHP7.0使用魔术方法数据如下,单位微秒μm// PHP7.0中连续调用脚本10000次sh test 10000 magic php set// 运行数据统计脚本sh analysis ./logs/__set_magic_php.log 10000// 结果avg: 17μmmax: 120μmmin: 11μm
<?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不使用魔术方法数据如下,单位微秒μm// PHP5.6中连续调用脚本10000次sh test 10000 no_magic php5 get// 运行数据统计脚本sh analysis ./logs/__get_no_magic_php5.log 10000// 结果avg: 28μm max: 590μm min: 20μm
// PHP5.6中连续调用脚本10000次 sh test 10000 magic php5 get// 运行数据统计脚本sh analysis ./logs/__get_magic_php5.log 10000// 结果avg: 28μmmax: 211μmmin: 22μm
// PHP7.0中连续调用脚本10000次 sh test 10000 no_magic php get// 运行数据统计脚本sh analysis ./logs/__get_no_magic_php.log 10000// 结果avg: 16μmmax: 295μmmin: 10μm
// PHP7.0中连续调用脚本10000次 sh test 10000 magic php get// 运行数据统计脚本sh analysis ./logs/__get_magic_php.log 10000// 结果avg: 19μmmax: 525μmmin: 12μm
새 형제 Laruence가 "마술 방법"을 사용하는 것은 권장하지 않는다고 언급한 적이 있습니다. 그 이후로 마법 방법이 관련될 때마다 블로거들은 무의식적으로 그것에 대해 생각할 것입니다. 이것이 좋은 사진인가요? 지난 2년 동안 일하느라 바빠서 새로운 지식을 배우느라 이 길에 대해 깊이 있는 탐구를 하지 못했고 올해는 블로거들이 깊이 있게 연구해야 할 해였습니다. , 이제 이 문제는 해결되어야 합니다. 먼저 Bird Brother Laruence가 자신의 블로그에서 언급한 내용을 살펴보겠습니다.
최적화 제안은 코드를 작성할 때 무엇이 느리고 무엇이 빠른지 알 수 있다면 사람들이 이를 악용하고 사용하는 것을 방지하기 위한 제안입니다. 이번 최적화 제안이 추구하는 효과인 매직 메소드 호출
위 내용은 PHP 성능 분석 매직 메소드 예제 공유의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!