ホームページ >バックエンド開発 >PHPチュートリアル >PHP で一般的に使用されるマジック メソッドのパフォーマンスの調査

PHP で一般的に使用されるマジック メソッドのパフォーマンスの調査

*文
*文オリジナル
2017-12-23 10:08:271971ブラウズ

パフォーマンスはコードを測定するための重要な基準となることがよくあります。私たちは日々のコーディングでいくつかのマジック メソッドをよく使用します。PHP が提供するこれらのマジック メソッドはプログラムのパフォーマンスに影響しますか?魔法のような方法の使用を減らす必要があるでしょうか?この記事では、テストの比較を使用して、マジック メソッドがパフォーマンスに及ぼす影響を理解します。

疑問

その魔法の方法は本当に性能が悪いのでしょうか?

PHP7 のマジック メソッドのパフォーマンスにまだ問題がありますか?

魔法の方法を合理的に使用するにはどうすればよいですか?

計画

私の計画は次のとおりです:

マジックメソッドを使用した場合と使用しない場合のスクリプト実行時間の差の統計的比較

PHP5.6.26でスクリプトをn回連続実行する- 1

統計的な実行時間の平均/最小/最大値

PHP7.0.12-2でスクリプトをn回連続実行

実行時間の統計的な平均/最小/最大値


テスト

__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 の実験を見てみましょう。

// 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 では、マジック メソッドは使用されていません。マイクロ秒 μ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 マジックメソッドを使用したデータは次のとおりです。単位はマイクロ秒です

// 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 を使用したスクリプトの平均実行時間は、__call を使用しない場合よりも遅くなり、約 2 マイクロ秒遅くなります。 php5.6でもphp7.0でも。

__callStatic

次に、__callStatic の実験を見てみましょう:

// 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 では、マジック メソッドは使用されません。マイクロ秒 μ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 マジックメソッドを使用したデータは次のとおりです。単位はマイクロ秒です
// 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 を使用したスクリプトの平均実行時間は、__callStatic を使用しない場合とほぼ同等です。 次に、__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

からわかります上記データ:

php5.6でもphp7.0でも、__setを使用したスクリプトの平均実行時間は、__setを使用しない場合よりも約2マイクロ秒遅くなります。


__get

次に、__get の実験を見てみましょう。

// 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 では、マジック メソッドは使用されません。マイクロ秒 μ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() という 5 つの一般的に使用されるマジックをテストしました。上記のテストに合格したら、疑問に答えるために戻ってきます

魔法のメソッドのパフォーマンスは本当に悪いですか?

回答: __construct の使用に加えて、ここで他のマジック メソッドを使用する時間は、およそ 10 マイクロ秒以内です。

PHP7 のマジック メソッドのパフォーマンスにまだ問題がありますか?

A: PHP7 でマジック メソッドを使用する場合と使用しない場合の違いは、PHP5.6 の場合とほぼ同じです。

魔法の方法を合理的に使用するにはどうすればよいですか?

A: テスト全体を通じて、マジック メソッドを使用しない場合の実行時間の差はおよそ 10 マイクロ秒以内であることがわかります。そのため、マジック メソッドを使用して開発コストを節約し、コードの構造を最適化できるのであれば、できるはずです。 10 マイクロ秒未満を犠牲にすることを検討してください。 __construct は高速であることを目的としているため、__construct を使用することに異論はありません。


以上がPHP で一般的に使用されるマジック メソッドのパフォーマンスの調査の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。