摘要:結(jié)語這里主要測試了,,,,這五個常用的且可有其他實現(xiàn)方式代替的魔法函數(shù)。里使用魔術(shù)方法的性能還是存在問題嗎答在中使用與不使用魔術(shù)方法之間的差異和在中近乎一致。
前言
曾經(jīng)記得鳥哥Laruence提過不建議使用"魔術(shù)方法",自此之后一旦涉及使用魔術(shù)方法的地方,我都會下意識的想一下,這樣寫真的好嗎?由于這一到兩年來一直忙于工作和學習新的知識,所以在這道坎兒上一直沒有做深入的探索一直恍恍惚惚過去了,今年是我進行深入學習的一年,因此現(xiàn)在必須對這個問題做個了結(jié)了。我們先來看看鳥哥Laruence博客曾經(jīng)提到的:
當我把PPT分享給公司的同事的時候, 會有人質(zhì)疑, 魔術(shù)方法都不讓用?疑惑
優(yōu)化的建議, 是建議, 是防止大家濫用, 肆無忌憚的用. 如果你能在寫代碼的時候, 能意識到, 什么慢, 什么快, 從而避免一些沒有必要的對魔術(shù)方法的調(diào)用, 那就是這個優(yōu)化建議所追求的效果了
魔術(shù)方法真的性能比較差嗎?
PHP7里使用魔術(shù)方法的性能還是存在問題嗎?
我們應該如何合理的使用魔術(shù)方法?
方案面對我的疑惑,我的方案是:
統(tǒng)計對比使用魔術(shù)方法和不使用魔術(shù)方法腳本執(zhí)行的時間差異
PHP5.6.26-1 下連續(xù)執(zhí)行腳本n次
統(tǒng)計執(zhí)行時間的平均值/最小值/最大值
PHP7.0.12-2 下連續(xù)執(zhí)行腳本n次
統(tǒng)計執(zhí)行時間的平均值/最小值/最大值
目前個人能力有限,只能通過這種方式,如果你有更好的方案或者建議可以告訴我,謝謝,haha~
測試 __construct首先我們先來看看構(gòu)造函數(shù)__construct的實驗,php腳本如下:
*/ require("./function.php"); if (!isset($argv[1])) { die("error: variable is_use_magic is empty"); } $is_use_magic = $argv[1]; /** * 構(gòu)造函數(shù)使用類名 */ class ClassOne { public function classOne() { # code... } } /** * 構(gòu)造函數(shù)使用魔術(shù)函數(shù)__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) . " ";
PHP5.6不使用魔術(shù)方法數(shù)據(jù)如下,單位微秒μm
// PHP5.6中連續(xù)調(diào)用腳本10000次 sh test 10000 no_magic php5 construct // 運行數(shù)據(jù)統(tǒng)計腳本 sh analysis ./logs/__construct_no_magic_php5.log 10000 // 結(jié)果 avg: 34μm max: 483μm min: 26μm
PHP5.6使用魔術(shù)方法數(shù)據(jù)如下,單位微秒μm
// PHP5.6中連續(xù)調(diào)用腳本10000次 sh test 10000 magic php5 construct // 運行數(shù)據(jù)統(tǒng)計腳本 sh analysis ./logs/__construct_magic_php5.log 10000 // 結(jié)果 avg: 28μm max: 896μm min: 20μm
PHP7.0不使用魔術(shù)方法數(shù)據(jù)如下,單位微秒μm
// PHP7.0中連續(xù)調(diào)用腳本10000次 sh test 10000 no_magic php construct // 運行數(shù)據(jù)統(tǒng)計腳本 sh analysis ./logs/__construct_no_magic_php.log 10000 // 結(jié)果 avg: 19μm max: 819μm min: 13μm
PHP7.0使用魔術(shù)方法數(shù)據(jù)如下,單位微秒μm
// PHP7.0中連續(xù)調(diào)用腳本10000次 sh test 10000 magic php construct // 運行數(shù)據(jù)統(tǒng)計腳本 sh analysis ./logs/__construct_magic_php.log 10000 // 結(jié)果 avg: 14μm max: 157μm min: 10μm
通過上面的數(shù)據(jù)我們可以看出:
使用__construct作為構(gòu)造函數(shù)的腳本執(zhí)行的平均時間是要快于使用類名作為構(gòu)造函數(shù)的,__大概快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]; /** * 構(gòu)造函數(shù)使用類名 */ class ClassOne { public function __construct() { # code... } public function test() { # code... } } /** * 構(gòu)造函數(shù)使用魔術(shù)函數(shù)__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) . " ";
PHP5.6不使用魔術(shù)方法數(shù)據(jù)如下,單位微秒μm
// PHP5.6中連續(xù)調(diào)用腳本10000次 sh test 10000 no_magic php5 call // 運行數(shù)據(jù)統(tǒng)計腳本 sh analysis ./logs/__call_no_magic_php5.log 10000 // 結(jié)果 avg: 27μm max: 206μm min: 20μm
PHP5.6使用魔術(shù)方法數(shù)據(jù)如下,單位微秒μm
// PHP5.6中連續(xù)調(diào)用腳本10000次 sh test 10000 magic php5 call // 運行數(shù)據(jù)統(tǒng)計腳本 sh analysis ./logs/__call_magic_php5.log 10000 // 結(jié)果 avg: 29μm max: 392μm min: 22μm
PHP7.0不使用魔術(shù)方法數(shù)據(jù)如下,單位微秒μm
// PHP7.0中連續(xù)調(diào)用腳本10000次 sh test 10000 no_magic php call // 運行數(shù)據(jù)統(tǒng)計腳本 sh analysis ./logs/__call_no_magic_php.log 10000 // 結(jié)果 avg: 16μm max: 256μm min: 10μm
PHP7.0使用魔術(shù)方法數(shù)據(jù)如下,單位微秒μm
// PHP7.0中連續(xù)調(diào)用腳本10000次 sh test 10000 magic php call // 運行數(shù)據(jù)統(tǒng)計腳本 sh analysis ./logs/__call_magic_php.log 10000 // 結(jié)果 avg: 18μm max: 2459μm min: 11μm
通過上面的數(shù)據(jù)我們可以看出:
使用__call的腳本執(zhí)行的平均時間是要慢于不使用,__大概慢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靜態(tài)方法 */ class ClassOne { public function __construct() { # code... } public static function test() { # code... } } /** * 使用重載實現(xiàn)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) . " ";
PHP5.6不使用魔術(shù)方法數(shù)據(jù)如下,單位微秒μm
// PHP5.6中連續(xù)調(diào)用腳本10000次 sh test 10000 no_magic php5 callStatic // 運行數(shù)據(jù)統(tǒng)計腳本 sh analysis ./logs/__callStatic_no_magic_php5.log 10000 // 結(jié)果 avg: 25μm max: 129μm min: 19μm
PHP5.6使用魔術(shù)方法數(shù)據(jù)如下,單位微秒μm
// PHP5.6中連續(xù)調(diào)用腳本10000次 sh test 10000 magic php5 callStatic // 運行數(shù)據(jù)統(tǒng)計腳本 sh analysis ./logs/__callStatic_magic_php5.log 10000 // 結(jié)果 avg: 28μm max: 580μm min: 20μm
PHP7.0不使用魔術(shù)方法數(shù)據(jù)如下,單位微秒μm
// PHP7.0中連續(xù)調(diào)用腳本10000次 sh test 10000 no_magic php callStatic // 運行數(shù)據(jù)統(tǒng)計腳本 sh analysis ./logs/__callStatic_no_magic_php.log 10000 // 結(jié)果 avg: 14μm max: 130μm min: 9μm
PHP7.0使用魔術(shù)方法數(shù)據(jù)如下,單位微秒μm
// PHP7.0中連續(xù)調(diào)用腳本10000次 sh test 10000 magic php callStatic // 運行數(shù)據(jù)統(tǒng)計腳本 sh analysis ./logs/__callStatic_magic_php.log 10000 // 結(jié)果 avg: 14μm max: 159μm min: 10μm
通過上面的數(shù)據(jù)我們可以看出:
在php5.6中使用__callStatic的腳本執(zhí)行的平均時間是要慢于不使用,__大概慢3微秒__;在php7.0中使用__callStatic的腳本執(zhí)行的平均時間是要大致等于不使用__callStatic的;__set
接著,我們來看看__set的實驗,php腳本如下:
*/ require("./function.php"); if (!isset($argv[1])) { die("error: variable is_use_magic is empty"); } $is_use_magic = $argv[1]; /** * 實現(xiàn)公共方法設置私有屬性 */ 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) . " ";
PHP5.6不使用魔術(shù)方法數(shù)據(jù)如下,單位微秒μm
// PHP5.6中連續(xù)調(diào)用腳本10000次 sh test 10000 no_magic php5 set // 運行數(shù)據(jù)統(tǒng)計腳本 sh analysis ./logs/__set_no_magic_php5.log 10000 // 結(jié)果 avg: 31μm max: 110μm min: 24μm
PHP5.6使用魔術(shù)方法數(shù)據(jù)如下,單位微秒μm
// PHP5.6中連續(xù)調(diào)用腳本10000次 sh test 10000 magic php5 set // 運行數(shù)據(jù)統(tǒng)計腳本 sh analysis ./logs/__set_magic_php5.log 10000 // 結(jié)果 avg: 33μm max: 138μm min: 25μm
PHP7.0不使用魔術(shù)方法數(shù)據(jù)如下,單位微秒μm
// PHP7.0中連續(xù)調(diào)用腳本10000次 sh test 10000 no_magic php set // 運行數(shù)據(jù)統(tǒng)計腳本 sh analysis ./logs/__set_no_magic_php.log 10000 // 結(jié)果 avg: 15μm max: 441μm min: 11μm
PHP7.0使用魔術(shù)方法數(shù)據(jù)如下,單位微秒μm
// PHP7.0中連續(xù)調(diào)用腳本10000次 sh test 10000 magic php set // 運行數(shù)據(jù)統(tǒng)計腳本 sh analysis ./logs/__set_magic_php.log 10000 // 結(jié)果 avg: 17μm max: 120μm min: 11μm
通過上面的數(shù)據(jù)我們可以看出:
使用__set的腳本執(zhí)行的平均時間是要慢于不使用,__大概慢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]; /** * 實現(xiàn)公共方法獲取私有屬性 */ 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) . " ";
PHP5.6不使用魔術(shù)方法數(shù)據(jù)如下,單位微秒μm
// PHP5.6中連續(xù)調(diào)用腳本10000次 sh test 10000 no_magic php5 get // 運行數(shù)據(jù)統(tǒng)計腳本 sh analysis ./logs/__get_no_magic_php5.log 10000 // 結(jié)果 avg: 28μm max: 590μm min: 20μm
PHP5.6使用魔術(shù)方法數(shù)據(jù)如下,單位微秒μm
// PHP5.6中連續(xù)調(diào)用腳本10000次 sh test 10000 magic php5 get // 運行數(shù)據(jù)統(tǒng)計腳本 sh analysis ./logs/__get_magic_php5.log 10000 // 結(jié)果 avg: 28μm max: 211μm min: 22μm
PHP7.0不使用魔術(shù)方法數(shù)據(jù)如下,單位微秒μm
// PHP7.0中連續(xù)調(diào)用腳本10000次 sh test 10000 no_magic php get // 運行數(shù)據(jù)統(tǒng)計腳本 sh analysis ./logs/__get_no_magic_php.log 10000 // 結(jié)果 avg: 16μm max: 295μm min: 10μm
PHP7.0使用魔術(shù)方法數(shù)據(jù)如下,單位微秒μm
// PHP7.0中連續(xù)調(diào)用腳本10000次 sh test 10000 magic php get // 運行數(shù)據(jù)統(tǒng)計腳本 sh analysis ./logs/__get_magic_php.log 10000 // 結(jié)果 avg: 19μm max: 525μm min: 12μm
通過上面的數(shù)據(jù)我們可以看出:
在php5.6中使用__get的腳本執(zhí)行的平均時間是要大致等于不使用__get的;在php7.0中使用__get的腳本執(zhí)行的平均時間是要慢于不使用,__大概慢3微秒__。結(jié)語
這里主要測試了__construct(), __call(), __callStatic(), __get(), __set()這五個常用的且可有其他實現(xiàn)方式代替的魔法函數(shù)。通過上面的測試再回來解答我的疑惑
魔術(shù)方法真的性能比較差嗎?
答:除了使用__construct之外,這里使用其他的魔法方法的時間大致慢10微妙以內(nèi)。
PHP7里使用魔術(shù)方法的性能還是存在問題嗎?
答:在PHP7中使用與不使用魔術(shù)方法之間的差異和在PHP5.6中近乎一致。
我們應該如何合理的使用魔術(shù)方法?
答:通過整個測試我們可以看出使不使用魔法方法這之間的執(zhí)行時間差異大致都是在10微妙以內(nèi)的,所以如果魔法方法可以很好的節(jié)省我們的開發(fā)成本和優(yōu)化我們的代碼結(jié)構(gòu),我們應該可以考慮犧牲掉這不到10微妙。而__construct是要快的,所以使用__construct應該沒什么異議。
腳本源碼https://github.com/TIGERB/eas...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/22474.html
摘要:新數(shù)組的值將被插入到數(shù)組的開頭。和都是動態(tài)調(diào)用函數(shù)的方法,區(qū)別在于參數(shù)的傳遞方式不同。方法三不使用魔法函數(shù)來實現(xiàn)只需要修改為函數(shù)即可重點在于,返回指針,方便調(diào)用后者函數(shù)。 在php中有很多字符串函數(shù),例如要先過濾字符串收尾的空格,再求出其長度,一般的寫法是: strlen(trim($str)) 如果要實現(xiàn)類似js中的鏈式操作,比如像下面這樣應該怎么寫? $str->trim()->s...
摘要:原文來自原文概述使用的函數(shù)允許你傳遞一個數(shù)組,然后移除重復的值,返回一個擁有唯一值的數(shù)組。有一個比較好而且更快的函數(shù)來替代使用函數(shù)來創(chuàng)建唯一的數(shù)組。 原文來自:http://www.hoohack.me/2016/01/11/faster-way-to-phps-array-unique-function/ 原文:Faster Alternative to PHP’s Array Un...
摘要:完整的一次調(diào)用流程遞歸調(diào)用棧遞歸同樣使用調(diào)用棧我們來分析下階乘的調(diào)用棧直接看圖遞歸注意事項遞歸會導致程序的性能變低如果遞歸嵌套很深,那么調(diào)用棧會很長,這將占用大量內(nèi)存,可能會導致棧溢出 平時在前端開發(fā)中,好像也沒啥用到遞歸的地方。不過這并不代表遞歸不重要,如果你看過一些框架的源碼,就會經(jīng)常見到它的影子:比如渲染虛擬DOM的render函數(shù),webpack中require依賴分析,Koa...
摘要:并且用驗證了中一系列的實質(zhì)就是魔法糖的本質(zhì)。抽絲剝繭我們首先看的編譯結(jié)果這是一個自執(zhí)行函數(shù),它接受一個參數(shù)就是他要繼承的父類,返回一個構(gòu)造函數(shù)。 如果你已經(jīng)看過第一篇揭秘babel的魔法之class魔法處理,這篇將會是一個延伸;如果你還沒看過,并且也不想現(xiàn)在就去讀一下,單獨看這篇也沒有關系,并不存在理解上的障礙。 上一篇針對Babel對ES6里面基礎class的編譯進行了分析。這一篇將...
閱讀 3503·2021-11-24 09:39
閱讀 781·2019-08-30 14:22
閱讀 3031·2019-08-30 13:13
閱讀 2310·2019-08-29 17:06
閱讀 2918·2019-08-29 16:22
閱讀 1255·2019-08-29 10:58
閱讀 2427·2019-08-26 13:47
閱讀 1628·2019-08-26 11:39