0

0

PHP常用魔术方法的性能探究

*文

*文

发布时间:2017-12-23 10:08:27

|

2086人浏览过

|

来源于php中文网

原创

性能往往是衡量代码很重要的一个标准。我们日常编码中经常会用到一些魔术方法,这些php提供的魔术方法是否会影响我们程序的性能呢?是否需要减少魔术方法 的使用呢?本文将通过测试对比来了解魔术方法对性能的影响。

疑惑

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

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

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

立即学习PHP免费学习笔记(深入)”;

方案

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

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

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

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

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

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

测试

__construct

首先我们先来看看构造函数__construct的实验,php脚本如下:


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

启科网络PHP商城系统
启科网络PHP商城系统

启科网络商城系统由启科网络技术开发团队完全自主开发,使用国内最流行高效的PHP程序语言,并用小巧的MySql作为数据库服务器,并且使用Smarty引擎来分离网站程序与前端设计代码,让建立的网站可以自由制作个性化的页面。 系统使用标签作为数据调用格式,网站前台开发人员只要简单学习系统标签功能和使用方法,将标签设置在制作的HTML模板中进行对网站数据、内容、信息等的调用,即可建设出美观、个性的网站。

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

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

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

__call

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


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

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

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

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

__callStatic

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


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

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

__set

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


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

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

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

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

__get

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


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

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

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

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

结语

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

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

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

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

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

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

立即学习PHP免费学习笔记(深入)”;

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

相关文章

数码产品性能查询
数码产品性能查询

该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

下载

相关标签:

php

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
菜鸟裹裹入口以及教程汇总
菜鸟裹裹入口以及教程汇总

本专题整合了菜鸟裹裹入口地址及教程分享,阅读专题下面的文章了解更多详细内容。

0

2026.01.22

Golang 性能分析与pprof调优实战
Golang 性能分析与pprof调优实战

本专题系统讲解 Golang 应用的性能分析与调优方法,重点覆盖 pprof 的使用方式,包括 CPU、内存、阻塞与 goroutine 分析,火焰图解读,常见性能瓶颈定位思路,以及在真实项目中进行针对性优化的实践技巧。通过案例讲解,帮助开发者掌握 用数据驱动的方式持续提升 Go 程序性能与稳定性。

9

2026.01.22

html编辑相关教程合集
html编辑相关教程合集

本专题整合了html编辑相关教程合集,阅读专题下面的文章了解更多详细内容。

56

2026.01.21

三角洲入口地址合集
三角洲入口地址合集

本专题整合了三角洲入口地址合集,阅读专题下面的文章了解更多详细内容。

51

2026.01.21

AO3中文版入口地址大全
AO3中文版入口地址大全

本专题整合了AO3中文版入口地址大全,阅读专题下面的的文章了解更多详细内容。

397

2026.01.21

妖精漫画入口地址合集
妖精漫画入口地址合集

本专题整合了妖精漫画入口地址合集,阅读专题下面的文章了解更多详细内容。

118

2026.01.21

java版本选择建议
java版本选择建议

本专题整合了java版本相关合集,阅读专题下面的文章了解更多详细内容。

3

2026.01.21

Java编译相关教程合集
Java编译相关教程合集

本专题整合了Java编译相关教程,阅读专题下面的文章了解更多详细内容。

16

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

11

2026.01.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 9.2万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 9.9万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号