>  기사  >  백엔드 개발  >  PHP 성능 분석 매직 메소드 예제 공유

PHP 성능 분석 매직 메소드 예제 공유

黄舟
黄舟원래의
2017-09-08 09:17:521496검색


새 형제 Laruence가 "마술 방법"을 사용하는 것이 권장되지 않는다고 언급한 것을 기억한 적이 있습니다. 그 이후로 마법 방법이 포함될 때마다 블로거들은 무의식적으로 그것에 대해 생각할 것입니다. 이것이 좋은 사진입니까? 지난 2년간 일하느라 바빠서 새로운 지식을 배우느라 이 고비에 대해 깊이 있게 탐구하지 못하고 올해는 블로거들이 깊이 있게 연구해야 할 해였습니다. , 이제 이 문제는 해결되어야 합니다. 먼저 Bird Brother Laruence가 자신의 블로그에서 언급한 내용을 살펴보겠습니다.

최적화 제안은 사람들이 코드를 남용하고 부주의하게 사용하는 것을 방지하기 위한 제안입니다. 코드를 작성할 때 무엇이 ​​느리고 무엇이 빠른지 알 수 있습니다. 매직 메소드에 대한 불필요한 호출, 이것이 바로 이번 최적화 제안이 추구하는 효과입니다

의심

매직 메소드의 성능이 정말 형편없나요?
PHP7에서 매직 메소드를 사용하는 성능에 여전히 문제가 있나요?
마술방법을 어떻게 합리적으로 사용해야 할까요?

Plan

의심에 직면하여 내 계획은 다음과 같습니다.

매직 메소드를 사용할 때와 사용하지 않을 때의 스크립트 실행 시간 차이를 통계적으로 비교합니다.
PHP5.6.26-1에서 스크립트를 n번 연속 실행합니다.
통계적 실행 시간 평균값/최소값/최대값
PHP7.0.12-2에서 스크립트를 n번 연속 실행합니다
실행 시간의 평균/최소값/최대값을 통계합니다
현재 제 개인 능력은 한계가 있어서 더 있으면 좋은 해결방법이나 제안사항 있으면 알려주시면 감사하겠습니다 ㅎㅎ~

Test

__construct

우선 생성자 __construct의 실험을 살펴보겠습니다. .php 스크립트는 다음과 같습니다.

<?php/**
 * 魔术方法性能探索
 *
 * 构造函数
 *
 * @author TIGERB <https://github.com/TIGERB>
 */require(&#39;./function.php&#39;);if (!isset($argv[1])) {
    die(&#39;error: variable is_use_magic is empty&#39;);
}
$is_use_magic = $argv[1];/**
 * 构造函数使用类名
 */class ClassOne
{    public function classOne()
    {
        # code...
    }
}/**
 * 构造函数使用魔术函数__construct
 */class ClassTwo
{    public function __construct()
    {
        # code...
    }
}

$a = getmicrotime();if ($is_use_magic === &#39;no_magic&#39;) {    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

다음으로 __call 실험을 살펴보겠습니다. PHP 스크립트는 다음과 같습니다.

<?php/**
 * 魔术方法性能探索
 *
 * 构造函数
 *
 * @author TIGERB <https://github.com/TIGERB>
 */require(&#39;./function.php&#39;);if (!isset($argv[1])) {    die(&#39;error: variable is_use_magic is empty&#39;);
}$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 === &#39;no_magic&#39;) {    $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

다음으로 __callStatic 실험을 살펴보겠습니다. PHP 스크립트는 다음과 같습니다.

<?php/**
 * 魔术方法性能探索
 *
 * 静态重载函数
 *
 * @author TIGERB <https://github.com/TIGERB>
 */require(&#39;./function.php&#39;);if (!isset($argv[1])) {    die(&#39;error: variable is_use_magic is empty&#39;);
}$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 === &#39;no_magic&#39;) {
    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(&#39;./function.php&#39;);if (!isset($argv[1])) {
    die(&#39;error: variable is_use_magic is empty&#39;);
}
$is_use_magic = $argv[1];/**
 * 实现公共方法设置私有属性
 */class ClassOne
{    /**
     * 私有属性
     *
     * @var string
     */
    private $someVariable = &#39;private&#39;;    public function __construct()
    {
        # code...
    }    public function setSomeVariable($value = &#39;&#39;)
    {
        $this->someVariable = $value;
    }
}/**
 * 使用_set设置私有属性
 */class ClassTwo
{    /**
     * 私有属性
     *
     * @var string
     */
    private $someVariable = &#39;private&#39;;    public function __construct()
    {
        # code...
    }    public function __set($name = &#39;&#39;, $value = &#39;&#39;)
    {
        $this->$name = $value;
    }
}

$a = getmicrotime();if ($is_use_magic === &#39;no_magic&#39;) {
    $instance = new ClassOne();
    $instance->setSomeVariable(&#39;public&#39;);
}else {
    $instance = new ClassTwo();
    $instance->someVariable = &#39;public&#39;;
}
$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은 다음과 같이 매직 메소드 데이터를 사용하며 단위는 마이크로초 μ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

위 데이터에서 우리는 참조:

__set를 사용하는 스크립트의 평균 실행 시간은 이를 사용하지 않는 것보다 느립니다. php5.6과 php7.0 모두에서 약 2마이크로초 더 느립니다.

__get

다음으로 __get 실험을 살펴보겠습니다. PHP 스크립트는 다음과 같습니다.

<?php/**
 * 魔术方法性能探索
 *
 * 读取私有属性__get
 *
 * @author TIGERB <https://github.com/TIGERB>
 */require(&#39;./function.php&#39;);if (!isset($argv[1])) {
    die(&#39;error: variable is_use_magic is empty&#39;);
}
$is_use_magic = $argv[1];/**
 * 实现公共方法获取私有属性
 */class ClassOne
{    /**
     * 私有属性
     *
     * @var string
     */
    private $someVariable = &#39;private&#39;;    public function __construct()
    {
        # code...
    }    public function getSomeVariable()
    {        return $this->someVariable;
    }
}/**
 * 使用_get获取私有属性
 */class ClassTwo
{    /**
     * 私有属性
     *
     * @var string
     */
    private $someVariable = &#39;private&#39;;    public function __construct()
    {
        # code...
    }    public function __get($name = &#39;&#39;)
    {        return $this->$name;
    }
}

$a = getmicrotime();if ($is_use_magic === &#39;no_magic&#39;) {
    $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은 마이크로초 단위로

// 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을 사용합니다. 데이터는 단위는 다음과 같습니다. 마이크로초 μ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은 다음과 같은 매직 방법 데이터를 사용하며, 단위는 마이크로초 μ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

위의 데이터를 통해 알 수 있습니다. PHP5.6에서 __get을 사용하는 스크립트의 평균 실행 시간은 대략 php7.0에서 __get을 사용하지 않는 것과 같습니다. __get을 사용하는 스크립트의 평균 실행 시간은 이를 사용하지 않을 때보다 약 3마이크로초 더 느립니다.

결론

여기서 우리는 주로 다른 구현으로 대체할 수 있는 일반적으로 사용되는 5가지 매직 함수인 __construct(), __call(), __callStatic(), __get(), __set()을 테스트했습니다. 위 테스트를 통과한 후 다시 질문에 답해 드리겠습니다

매직 메소드의 성능이 정말 형편없나요?

답변: __construct를 사용하는 것 외에도 여기서 다른 마법 메서드를 사용하는 시간은 대략 10마이크로초 이내입니다.

PHP7의 매직 메소드 성능에 여전히 문제가 있나요?

A: PHP7에서 매직 메소드를 사용하는 것과 사용하지 않는 것의 차이는 PHP5.6과 거의 같습니다.

마법을 어떻게 합리적으로 사용해야 할까요?

A: 전체 테스트를 통해 매직 메서드를 사용하지 않은 경우의 실행 시간 차이가 대략 10마이크로초 이내라는 것을 알 수 있습니다. 따라서 매직 메서드를 사용하면 개발 비용을 절약하고 코드인 구조를 최적화할 수 있다면 다음과 같은 작업을 수행할 수 있을 것입니다. 10마이크로초 미만의 희생을 고려하는 것입니다. __construct는 속도가 빠르도록 설계되었으므로 __construct 사용에 반대할 필요가 없습니다.

새 형제 Laruence가 "마술 방법"을 사용하는 것은 권장하지 않는다고 언급한 적이 있습니다. 그 이후로 마법 방법이 관련될 때마다 블로거들은 무의식적으로 그것에 대해 생각할 것입니다. 이것이 좋은 사진인가요? 지난 2년 동안 일하느라 바빠서 새로운 지식을 배우느라 이 길에 대해 깊이 있는 탐구를 하지 못했고 올해는 블로거들이 깊이 있게 연구해야 할 해였습니다. , 이제 이 문제는 해결되어야 합니다. 먼저 Bird Brother Laruence가 자신의 블로그에서 언급한 내용을 살펴보겠습니다.

최적화 제안은 코드를 작성할 때 무엇이 ​​느리고 무엇이 빠른지 알 수 있다면 사람들이 이를 악용하고 사용하는 것을 방지하기 위한 제안입니다. 이번 최적화 제안이 추구하는 효과인 매직 메소드 호출

위 내용은 PHP 성능 분석 매직 메소드 예제 공유의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.