• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

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

php 搞代码 3年前 (2022-01-22) 20次浏览 已收录 0个评论

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

疑惑

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

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

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

方案

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

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

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

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

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

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

测试

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

// PHP5.6中连续调用脚本10000次sh test 10000 no_magic php5 construct// 运行数据统计脚本sh analysis ./logs/__construct_no_magic_php5.log 10000// 结果avg: 34μsmax: 483μsmin: 26μs

PHP5.6使用魔术方法数据如下,单位微秒μs

// PHP5.6中连续调用脚本10000次sh test 10000 magic php5 construct// 运行数据统计脚本sh analysis ./logs/__construct_magic_php5.log 10000// 结果avg:<a>本2文来*源gao($daima.com搞@代@#码(网</a><strong>搞gaodaima代码</strong> 28μsmax: 896μsmin: 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μsmax: 819μsmin: 13μs

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

// PHP7.0中连续调用脚本10000次sh test 10000 magic php construct// 运行数据统计脚本sh analysis ./logs/__construct_magic_php.log 10000// 结果avg: 14μsmax: 157μsmin: 10μs

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

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

// PHP5.6中连续调用脚本10000次sh test 10000 no_magic php5 call// 运行数据统计脚本sh analysis ./logs/__call_no_magic_php5.log 10000// 结果avg: 27μsmax: 206μsmin: 20μs

PHP5.6使用魔术方法数据如下,单位微秒μs

// PHP5.6中连续调用脚本10000次sh test 10000 magic php5 call// 运行数据统计脚本sh analysis ./logs/__call_magic_php5.log 10000// 结果avg: 29μsmax: 392μsmin: 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μsmax: 256μsmin: 10μs

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

// PHP7.0中连续调用脚本10000次sh test 10000 magic php call// 运行数据统计脚本sh analysis ./logs/__call_magic_php.log 10000// 结果avg: 18μsmax: 2459μsmin: 11μs

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

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

// PHP5.6中连续调用脚本10000次sh test 10000 no_magic php5 callStatic// 运行数据统计脚本sh analysis ./logs/__callStatic_no_magic_php5.log 10000// 结果avg: 25μsmax: 129μsmin: 19μs

PHP5.6使用魔术方法数据如下,单位微秒μs

// PHP5.6中连续调用脚本10000次sh test 10000 magic php5 callStatic// 运行数据统计脚本sh analysis ./logs/__callStatic_magic_php5.log 10000// 结果avg: 28μsmax: 580μsmin: 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μsmax: 130μsmin: 9μs

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

// PHP7.0中连续调用脚本10000次sh test 10000 magic php callStatic// 运行数据统计脚本sh analysis ./logs/__callStatic_magic_php.log 10000// 结果avg: 14μsmax: 159μsmin: 10μs

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

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

// PHP5.6中连续调用脚本10000次sh test 10000 no_magic php5 set// 运行数据统计脚本sh analysis ./logs/__set_no_magic_php5.log 10000// 结果avg: 31μsmax: 110μsmin: 24μs

PHP5.6使用魔术方法数据如下,单位微秒μs

// PHP5.6中连续调用脚本10000次sh test 10000 magic php5 set// 运行数据统计脚本sh analysis ./logs/__set_magic_php5.log 10000// 结果avg: 33μsmax: 138μsmin: 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μsmax: 441μsmin: 11μs

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

// PHP7.0中连续调用脚本10000次sh test 10000 magic php set// 运行数据统计脚本sh analysis ./logs/__set_magic_php.log 10000// 结果avg: 17μsmax: 120μsmin: 11μs

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

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

// PHP5.6中连续调用脚本10000次sh test 10000 no_magic php5 get// 运行数据统计脚本sh analysis ./logs/__get_no_magic_php5.log 10000// 结果avg: 28μsmax: 590μsmin: 20μs

PHP5.6使用魔术方法数据如下,单位微秒μs

// PHP5.6中连续调用脚本10000次sh test 10000 magic php5 get// 运行数据统计脚本sh analysis ./logs/__get_magic_php5.log 10000// 结果avg: 28μsmax: 211μsmin: 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μsmax: 295μsmin: 10μs

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

// PHP7.0中连续调用脚本10000次sh test 10000 magic php get// 运行数据统计脚本sh analysis ./logs/__get_magic_php.log 10000// 结果avg: 19μsmax: 525μsmin: 12μs

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

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

结语

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

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

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

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

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

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

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

以上就是PHP常用魔术方法的性能探究的详细内容,更多请关注搞代码gaodaima其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:PHP常用魔术方法的性能探究

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址