Heim  >  Artikel  >  Backend-Entwicklung  >  Leistungsuntersuchung häufig verwendeter magischer Methoden in PHP

Leistungsuntersuchung häufig verwendeter magischer Methoden in PHP

*文
*文Original
2017-12-23 10:08:271914Durchsuche

Leistung ist oft ein wichtiges Kriterium für die Messung von Code. Wir verwenden in unserer täglichen Codierung häufig einige magische Methoden. Werden diese von PHP bereitgestellten magischen Methoden die Leistung unseres Programms beeinflussen? Ist es notwendig, den Einsatz magischer Methoden zu reduzieren? In diesem Artikel werden Testvergleiche verwendet, um die Auswirkungen magischer Methoden auf die Leistung zu verstehen.

Zweifel

Ist die magische Methode wirklich leistungsschwach?

Gibt es immer noch ein Problem mit der Leistung bei der Verwendung magischer Methoden in PHP7?

Wie sollten wir magische Methoden sinnvoll einsetzen?

Plan

Trotz meiner Zweifel ist mein Plan:

Statistisch den Zeitunterschied zwischen der Skriptausführung mit der magischen Methode und der Nichtverwendung der magischen Methode vergleichen

Ausführen das Skript n-mal kontinuierlich unter PHP5.6.26-1 ausführen

Statistiken zur durchschnittlichen/minimalen/maximalen Ausführungszeit

Führen Sie das Skript n-mal kontinuierlich unter PHP7.0.12-2 aus

Statistischer Durchschnitt/minimale/maximale Ausführungszeit


Test

__construct

Schauen wir uns zunächst das Experiment der Konstruktorfunktion __construct an:

<?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 verwendet nicht die magische Methode. Die Daten sind wie folgt Mikrosekunden μ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 verwendet die magische Methode und die Daten sind wie folgt, die Einheit ist Mikrosekunden μ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 verwendet nicht die magische Methode und die Die Daten sind wie folgt, die Einheit ist Mikrosekunde μ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 verwendet die magischen Methodendaten wie folgt, die Einheit ist Mikrosekunde μ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

Aus den obigen Daten können wir siehe:


Verwenden Sie __construct als Die durchschnittliche Ausführungszeit des Konstruktorskripts ist schneller als die Verwendung des Klassennamens als Konstruktor, etwa 5 bis 6 Mikrosekunden schneller, egal ob in PHP5. 6 oder PHP7.0.


__call

Als nächstes schauen wir uns das __call-Experiment an. Das PHP-Skript ist wie folgt folgt:

<?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";

Die Daten von PHP5.6 ohne magische Methode sind wie folgt, die Einheit ist Mikrosekunde μ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

Die Daten von PHP5.6 mit magischer Methode sind wie folgt , die Einheit ist Mikrosekunde μ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 verwendet nicht die magische Methode. Die Daten sind wie folgt, die Einheit ist Mikrosekunde μ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 verwendet die Magische Methode. Die Daten sind wie folgt, die Einheit ist Mikrosekunde μ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

Aus den oben genannten Daten können wir ersehen:

Die durchschnittliche Ausführungszeit von Skripten, die __call verwenden, ist langsamer als Wenn Sie es nicht verwenden, ist es etwa 2 Mikrosekunden langsamer, egal ob in PHP5.6 oder PHP7.0.


__callStatic

Als nächstes schauen wir uns das __callStatic-Experiment an folgt:

<?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";

Die Daten von PHP5.6 ohne magische Methode sind wie folgt, die Einheit ist Mikrosekunde μ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

Die Daten von PHP5.6 mit magischer Methode sind wie folgt , die Einheit ist Mikrosekunde μ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 verwendet nicht die magische Methode. Die Daten sind wie folgt, die Einheit ist Mikrosekunde μ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 verwendet die Magische Methode. Die Daten sind wie folgt, die Einheit ist Mikrosekunde μ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

Aus den oben genannten Daten können wir ersehen:

Die durchschnittliche Ausführungszeit von Skripten mit __callStatic in PHP5. 6 ist langsamer als ohne, etwa 3 Mikrosekunden; Skripte mit __callStatic in php7.0 Die durchschnittliche Ausführungszeit sollte ungefähr der ohne __callStatic entsprechen


__set

Dann werfen wir einen Blick auf das __set-Experiment:

<?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 verwendet keine magische Methode . Die Daten sind wie folgt, in Mikrosekunden

// 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 verwendet Magie. Die Methodendaten sind wie folgt, die Einheit ist Mikrosekunden μ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 Wenn Sie die magische Methode nicht verwenden, lauten die Daten wie folgt, die Einheit ist Mikrosekunde μ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 verwendet die magische Methode. Die Daten lauten wie folgt, die Einheit ist Mikrosekunde μ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

Von Die obigen Daten können wir sehen:

Die durchschnittliche Ausführungszeit eines Skripts, das __set verwendet, ist langsamer als bei Nichtverwendung, etwa 2 Mikrosekunden langsamer, unabhängig davon, ob es sich um PHP5.6 oder PHP7.0 handelt.


__get

Als nächstes schauen wir uns das __get-Experiment an. Das PHP-Skript ist wie folgt folgt:

<?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";

Die Daten von PHP5.6 ohne magische Methode sind wie folgt, die Einheit ist Mikrosekunde μ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

Die Daten von PHP5.6 mit magischer Methode sind wie folgt , die Einheit ist Mikrosekunde μ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 verwendet nicht die magische Methode. Die Daten sind wie folgt, die Einheit ist Mikrosekunde μ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 verwendet die Magische Methode. Die Daten sind wie folgt, die Einheit ist Mikrosekunde μ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

Aus den oben genannten Daten können wir ersehen:

Die durchschnittliche Ausführungszeit von Skripten mit __get in PHP5. 6 entspricht in etwa der durchschnittlichen Ausführungszeit von Skripten, die __get nicht verwenden. In PHP7.0 ist die Zeit langsamer als bei Nichtverwendung, etwa 3 Mikrosekunden langsamer.


Fazit

Hier haben wir hauptsächlich __construct(), __call(), __callStatic() getestet, __get(), __set() sind fünf häufig verwendete magische Funktionen, die durch andere Implementierungen ersetzt werden können. Nachdem ich den obigen Test bestanden habe, werde ich zurückkommen, um meine Fragen zu beantworten


Ist die magische Methode wirklich leistungsschwach?

A: Zusätzlich zur Verwendung von __construct beträgt die Zeit für die Verwendung anderer magischer Methoden hier etwa 10 Mikrosekunden.


Gibt es immer noch ein Problem mit der Leistung bei der Verwendung magischer Methoden in PHP7?

A: Der Unterschied zwischen der Verwendung und Nichtverwendung magischer Methoden in PHP7 ist fast der gleiche wie in PHP5.6.


Wie sollten wir magische Methoden sinnvoll einsetzen?

A: Während des gesamten Tests können wir sehen, dass der Unterschied in der Ausführungszeit zwischen der Nichtverwendung der magischen Methode ungefähr innerhalb von 10 Mikrosekunden liegt. Wenn die magische Methode also unsere Entwicklungskosten einsparen und unsere Codestruktur optimieren kann, können wir sollte in der Lage sein, weniger als 10 Mikrosekunden zu opfern. __construct soll schnell sein, daher sollte es keine Einwände gegen die Verwendung von __construct geben.


Das obige ist der detaillierte Inhalt vonLeistungsuntersuchung häufig verwendeter magischer Methoden in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn