>백엔드 개발 >PHP 튜토리얼 >PHP의 일반적인 매직 메소드 성능 탐색

PHP의 일반적인 매직 메소드 성능 탐색

*文
*文원래의
2017-12-23 10:08:271964검색

성능은 코드를 측정하는 중요한 기준인 경우가 많습니다. 우리는 일상적인 코딩에서 몇 가지 매직 메소드를 자주 사용합니다. PHP가 제공하는 이러한 매직 메소드가 프로그램 성능에 영향을 미칠까요? 매직 메소드의 사용을 줄여야 합니까? 이 기사에서는 테스트 비교를 사용하여 매직 메소드가 성능에 미치는 영향을 이해합니다.

의심

매직메소드는 정말 성능이 떨어지는 걸까요?

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에서는 마이크로초 단위의 데이터가

입니다.
// 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은 매직 방식을 사용합니다. 단위는 마이크로초입니다. 초 μ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은 매직 방식을 사용하지 않습니다. __construct를 생성자로 사용하는 스크립트의 시간은 클래스 이름을 생성자로 사용하는 것보다 빠르며, php5.6에서든 php7.0에서든 약 5~6 마이크로초 더 빠릅니다.


__call

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

// 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

PHP5.6에서는 매직 메소드를 사용하지 않습니다. microseconds μ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
PHP5.6 매직 방식을 사용한 데이터의 단위는 마이크로초 μs
<?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";
PHP7.0 매직 방식을 사용하지 않은 데이터의 단위는 마이크로초 μ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

PHP7입니다. 0 매직 메소드를 사용한 데이터는 다음과 같으며 단위는 마이크로초 μ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

위의 데이터를 통해 알 수 있습니다.

__call을 사용하는 스크립트의 평균 실행 시간은 이를 사용하지 않는 경우보다 약 2마이크로초 정도 느립니다. php5.6이든 php7.0이든.

__callStatic

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

// 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

PHP5.6에서는 매직 메소드를 사용하지 않습니다. microseconds μ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
PHP5.6 매직 방식을 사용한 데이터의 단위는 마이크로초 μs
<?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";
PHP7.0 매직 방식을 사용하지 않은 데이터의 단위는 마이크로초 μ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

PHP7입니다. 0 매직 메소드를 사용한 데이터는 다음과 같으며 단위는 마이크로초 μ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

위의 데이터를 통해 알 수 있습니다.

php5.6에서 __callStatic을 사용하는 스크립트의 평균 실행 시간은 이를 사용하지 않을 때보다 느리고, 약 3 마이크로초; php7.0에서 __callStatic을 사용하는 스크립트의 평균 실행 시간은

__set

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

// 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

PHP5.6은 매직 메소드를 사용하지 않습니다. 데이터는 마이크로 단위입니다. 초 μ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
PHP5.6에서 매직 메소드를 사용한 데이터는 다음과 같습니다. 단위는 마이크로초 μs입니다.
<?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";
PHP7.0 매직 메소드를 사용하지 않은 데이터의 단위는 마이크로초 μs
// 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

PHP7.0 매직 메소드를 사용한 데이터의 단위는 마이크로초 μ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

에서 확인할 수 있습니다. 위 데이터:

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

__get

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

// 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

PHP5.6에서는 매직 메소드를 사용하지 않습니다. microseconds μ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
PHP5.6 매직 방식을 사용한 데이터의 단위는 마이크로초 μs
<?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";
PHP7.0 매직 방식을 사용하지 않은 데이터의 단위는 마이크로초 μ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

PHP7입니다. 0 매직 메소드를 사용한 데이터는 다음과 같습니다. 단위는 마이크로초 μ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

위의 데이터를 통해 다음을 알 수 있습니다.

php5.6에서 __get을 사용한 스크립트의 평균 실행 시간은 __get을 사용하지 않은 것과 대략 동일합니다. php7.0에서 __get을 사용하는 스크립트의 평균 실행 시간은 사용하지 않는 것보다 약 3마이크로초 정도 느립니다.

결론

여기서 우리는 주로 일반적으로 사용되는 다섯 가지 매직인 __construct(), __call(), __callStatic(), __get(), __set()을 테스트했습니다. 이는 다른 구현 방법 함수로 대체될 수 있습니다. 위 테스트를 통과한 후, 다시 돌아와서 제 의심에 대한 답을 드리겠습니다

매직 메소드의 성능이 정말 형편없나요? 답변: __construct를 사용하는 것 외에도 여기서 다른 마법 메서드를 사용하는 시간은 대략 10마이크로초 이내입니다.


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

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


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

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


위 내용은 PHP의 일반적인 매직 메소드 성능 탐색의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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