cari

关于PHP 魔法函数性能

Dec 05, 2017 am 11:19 AM
phpfungsiprestasi

有人不建议使用”魔术方法”,会有人质疑, 魔术方法都不让用?其实也不是,本文就和大家分析一下关于PHP 魔法函数的性能。

优化的建议, 是建议, 是防止大家滥用, 肆无忌惮的用. 如果你能在写代码的时候, 能意识到, 什么慢, 什么快, 从而避免一些没有必要的对魔术方法的调用, 那就是这个优化建议所追求的效果了

疑惑

  1. 魔术方法真的性能比较差吗?

  2. PHP7里使用魔术方法的性能还是存在问题吗?

  3. 我们应该如何合理的使用魔术方法?

方案

面对我的疑惑,我的方案是:

  • 统计对比使用魔术方法和不使用魔术方法脚本执行的时间差异

  • PHP5.6.26-1 下连续执行脚本n次

  • 统计执行时间的平均值/最小值/最大值

  • PHP7.0.12-2 下连续执行脚本n次

  • 统计执行时间的平均值/最小值/最大值

目前个人能力有限,只能通过这种方式,如果你有更好的方案或者建议可以告诉我,谢谢,haha~

测试

__construct

首先我们先来看看构造函数__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中连续调用脚本10000次
sh test 10000 magic php5 construct

// 运行数据统计脚本
sh analysis ./logs/__construct_magic_php5.log 10000

// 结果
avg: 28μm
max: 896μm
min: 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μm
max: 819μm
min: 13μm

 

  • PHP7.0使用魔术方法数据如下,单位微秒μm

// PHP7.0中连续调用脚本10000次
sh test 10000 magic php construct

// 运行数据统计脚本
sh analysis ./logs/__construct_magic_php.log 10000

// 结果
avg: 14μm
max: 157μm
min: 10μm

 

通过上面的数据我们可以看出:

使用__construct作为构造函数的脚本执行的平均时间是要快于使用类名作为构造函数的, 大概快5到6微秒 ,不论是在php5.6还是php7.0中。

__call

接着,我们来看看__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使用魔术方法数据如下,单位微秒μm

// PHP5.6中连续调用脚本10000次
sh test 10000 magic php5 call

// 运行数据统计脚本
sh analysis ./logs/__call_magic_php5.log 10000

// 结果
avg: 29μm
max: 392μm
min: 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μm
max: 256μm
min: 10μm

 

  • PHP7.0使用魔术方法数据如下,单位微秒μm

// PHP7.0中连续调用脚本10000次
sh test 10000 magic php call

// 运行数据统计脚本
sh analysis ./logs/__call_magic_php.log 10000

// 结果
avg: 18μm
max: 2459μm
min: 11μm

 

通过上面的数据我们可以看出:

使用__call的脚本执行的平均时间是要慢于不使用, 大概慢2微秒 ,不论是在php5.6还是php7.0中。

__callStatic

接着,我们来看看__callStatic的实验,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];

/**
 * 存在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使用魔术方法数据如下,单位微秒μm

// PHP5.6中连续调用脚本10000次
sh test 10000 magic php5 callStatic

// 运行数据统计脚本
sh analysis ./logs/__callStatic_magic_php5.log 10000

// 结果
avg: 28μm
max: 580μm
min: 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μm
max: 130μm
min: 9μm

 

  • PHP7.0使用魔术方法数据如下,单位微秒μm

// PHP7.0中连续调用脚本10000次
sh test 10000 magic php callStatic

// 运行数据统计脚本
sh analysis ./logs/__callStatic_magic_php.log 10000

// 结果
avg: 14μm
max: 159μm
min: 10μm

 

通过上面的数据我们可以看出:

在php5.6中使用__callStatic的脚本执行的平均时间是要慢于不使用, 大概慢3微秒 ;在php7.0中使用__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使用魔术方法数据如下,单位微秒μm

// PHP5.6中连续调用脚本10000次
sh test 10000 magic php5 set
// 运行数据统计脚本
sh analysis ./logs/__set_magic_php5.log 10000

// 结果
avg: 33μm
max: 138μm
min: 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μm
max: 441μm
min: 11μm

 

  • PHP7.0使用魔术方法数据如下,单位微秒μm

// PHP7.0中连续调用脚本10000次
sh test 10000 magic php set
// 运行数据统计脚本
sh analysis ./logs/__set_magic_php.log 10000

// 结果
avg: 17μm
max: 120μm
min: 11μm

 

通过上面的数据我们可以看出:

使用__set的脚本执行的平均时间是要慢于不使用, 大概慢2微秒 ,不论是在php5.6还是php7.0中。

__get

接着,我们来看看__get的实验,php脚本如下:

<?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使用魔术方法数据如下,单位微秒μm

// PHP5.6中连续调用脚本10000次
sh test 10000 magic php5 get
// 运行数据统计脚本
sh analysis ./logs/__get_magic_php5.log 10000

// 结果
avg: 28μm
max: 211μm
min: 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μm
max: 295μm
min: 10μm

 

  • PHP7.0使用魔术方法数据如下,单位微秒μm

// PHP7.0中连续调用脚本10000次
sh test 10000 magic php get
// 运行数据统计脚本
sh analysis ./logs/__get_magic_php.log 10000

// 结果
avg: 19μm
max: 525μm
min: 12μm

 

通过上面的数据我们可以看出:

在php5.6中使用__get的脚本执行的平均时间是要大致等于不使用__get的;在php7.0中使用__get的脚本执行的平均时间是要慢于不使用, 大概慢3微秒

结语

这里主要测试了__construct(), __call(), __callStatic(), __get(), __set()这五个常用的且可有其他实现方式代替的魔法函数。通过上面的测试再回来解答我的疑惑

  1. 魔术方法真的性能比较差吗?

答:除了使用__construct之外,这里使用其他的魔法方法的时间大致慢10微妙以内。

  1. PHP7里使用魔术方法的性能还是存在问题吗?

答:在PHP7中使用与不使用魔术方法之间的差异和在PHP5.6中近乎一致。

  1. 我们应该如何合理的使用魔术方法?

答:通过整个测试我们可以看出使不使用魔法方法这之间的执行时间差异大致都是在10微妙以内的,所以如果魔法方法可以很好的节省我们的开发成本和优化我们的代码结构,我们应该可以考虑牺牲掉这不到10微妙。而__construct是要快的,所以使用__construct应该没什么异议。

以上内容就是关于PHP 魔法函数性能分析,希望对大家有帮助。

相关推荐:

php中关于魔法函数以及魔法常量的使用详解

详解PHP魔法函数性能的示例代码

PHP魔法函数应用详解_PHP教程

Atas ialah kandungan terperinci 关于PHP 魔法函数性能. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Cara membuat aplikasi php lebih cepatCara membuat aplikasi php lebih cepatMay 12, 2025 am 12:12 AM

Tomakephpapplicationsfaster, ikutiTheseSteps: 1) UseopcodecachinglikeopcachetostorePrecompiledscriptbytecode.2) minimizedatabasequeriesbyusingquerycachingandeficientindexing.3)

Senarai Semak Pengoptimuman Prestasi PHP: Meningkatkan Kelajuan SekarangSenarai Semak Pengoptimuman Prestasi PHP: Meningkatkan Kelajuan SekarangMay 12, 2025 am 12:07 AM

ToimprovePhpapPlicationspeed, ikutiTheSesteps: 1) EnableopCodeCachingWithApcutoreduceScriptExecutionTime.2) pelaksanaanDatabasequerycachingingPdotominimizedataBaseHits.3)

Suntikan Ketergantungan PHP: Meningkatkan kebolehlaksanaan kodSuntikan Ketergantungan PHP: Meningkatkan kebolehlaksanaan kodMay 12, 2025 am 12:03 AM

Suntikan ketergantungan (DI) dengan ketara meningkatkan kesesuaian kod PHP oleh kebergantungan transitif secara eksplisit. 1) Kelas Decoupling dan pelaksanaan khusus menjadikan ujian dan penyelenggaraan lebih fleksibel. 2) Di antara tiga jenis, pembina menyuntik kebergantungan ekspresi eksplisit untuk memastikan keadaan konsisten. 3) Gunakan bekas DI untuk menguruskan kebergantungan kompleks untuk meningkatkan kualiti kod dan kecekapan pembangunan.

Pengoptimuman Prestasi PHP: Pengoptimuman Pertanyaan Pangkalan DataPengoptimuman Prestasi PHP: Pengoptimuman Pertanyaan Pangkalan DataMay 12, 2025 am 12:02 AM

DatabaseQueryoptimizationInpinvolvesseverSlegatiesToenhancePratePratePratePratePratePregiesToRperformance.1) selectOnlynessaryColumnStoReducedatatatransfer.2) UseIndexingTospeedupdatareTrieval.3) PrevancequerycachingToStoreresultSoffReFfeFfffffffffffffffffffffffffffffffffffffffffffferseprewfffffffffffersepresseprespersepresperseprespersepresperseprespersepresperseprespers

Panduan Mudah: Menghantar E -mel dengan Skrip PHPPanduan Mudah: Menghantar E -mel dengan Skrip PHPMay 12, 2025 am 12:02 AM

Phpisusedforsendingemailsduetoitsbuilt-inmail () functionAndSupportivelibrariesLikePhpmailerandswiftmailer.1) usethemail () functionforbasiceMails, butithaslimitations.2) scorkphpmailerforadvancedfeatures

Prestasi PHP: Mengenalpasti dan menetapkan kesesakanPrestasi PHP: Mengenalpasti dan menetapkan kesesakanMay 11, 2025 am 12:13 AM

Kesesakan prestasi PHP boleh diselesaikan melalui langkah -langkah berikut: 1) Gunakan XDEBUG atau Blackfire untuk analisis prestasi untuk mengetahui masalah; 2) Mengoptimumkan pertanyaan pangkalan data dan menggunakan cache, seperti APCU; 3) Gunakan fungsi yang cekap seperti array_filter untuk mengoptimumkan operasi array; 4) Konfigurasi Opcache untuk cache bytecode; 5) mengoptimumkan bahagian depan, seperti mengurangkan permintaan HTTP dan mengoptimumkan gambar; 6) Memantau dan mengoptimumkan prestasi secara berterusan. Melalui kaedah ini, prestasi aplikasi PHP dapat ditingkatkan dengan ketara.

Suntikan Ketergantungan untuk PHP: Ringkasan CepatSuntikan Ketergantungan untuk PHP: Ringkasan CepatMay 11, 2025 am 12:09 AM

DependencyInjection (DI) inphpisadesignPatternThatManagesandReducesclassdependencies, enhancingcodemodularity, testility, andmaintainability.itallowspassingdependenciesLikedatabaseconnectionstoclassesesparameters, fasilitasieAseAsiShanandscalability.

Meningkatkan Prestasi PHP: Strategi & Teknik CachingMeningkatkan Prestasi PHP: Strategi & Teknik CachingMay 11, 2025 am 12:08 AM

CachingimprovesphpperformanceSbebyStoringResultsofcomputationsorqueriesforquickretrieval, reducingserverloadandenhancingResponsetimes.effectiveStRegiesClude: 1) Opcodecaching, yang

See all articles

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Nordhold: Sistem Fusion, dijelaskan
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers of the Witch Tree - Cara Membuka Kunci Cangkuk Bergelut
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌

Alat panas

SublimeText3 versi Inggeris

SublimeText3 versi Inggeris

Disyorkan: Versi Win, menyokong gesaan kod!

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

SecLists

SecLists

SecLists ialah rakan penguji keselamatan muktamad. Ia ialah koleksi pelbagai jenis senarai yang kerap digunakan semasa penilaian keselamatan, semuanya di satu tempat. SecLists membantu menjadikan ujian keselamatan lebih cekap dan produktif dengan menyediakan semua senarai yang mungkin diperlukan oleh penguji keselamatan dengan mudah. Jenis senarai termasuk nama pengguna, kata laluan, URL, muatan kabur, corak data sensitif, cangkerang web dan banyak lagi. Penguji hanya boleh menarik repositori ini ke mesin ujian baharu dan dia akan mempunyai akses kepada setiap jenis senarai yang dia perlukan.

MantisBT

MantisBT

Mantis ialah alat pengesan kecacatan berasaskan web yang mudah digunakan yang direka untuk membantu dalam pengesanan kecacatan produk. Ia memerlukan PHP, MySQL dan pelayan web. Lihat perkhidmatan demo dan pengehosan kami.

VSCode Windows 64-bit Muat Turun

VSCode Windows 64-bit Muat Turun

Editor IDE percuma dan berkuasa yang dilancarkan oleh Microsoft