静态方法的性能与函数的性能 [英] Performance of static methods vs. functions
问题描述
在PHP中(与我最初认为的不同),调用静态方法比调用简单函数的开销要大。
在非常简单的工作台上,开销超过调用时间的30% (该方法只返回参数):// bench static method
$starttime = microtime(true);
for ($i = 0; $i< 10*1000*1000; $i++)
SomeClass::doTest($i);
echo "Static Time: " , (microtime(true)-$starttime) , " ms
";
// bench object method
$starttime = microtime(true);
for ($i = 0; $i< 10*1000*1000; $i++)
$someObj->doTest($i);
echo "Object Time: " , (microtime(true)-$starttime) , " ms
";
// bench function
$starttime = microtime(true);
for ($i = 0; $i< 10*1000*1000; $i++)
something_doTest($i);
echo "Function Time: " , (microtime(true)-$starttime) , " ms
";
输出:
Static Time: 0.640204906464 ms
Object Time: 0.48961687088 ms
Function Time: 0.438289880753 ms
我知道实际时间仍然可以忽略不计,除非我真的调用了100万次,但事实是它就在那里。
有人愿意尝试解释一下幕后发生的事情吗?
更新:
-新增对象方法工作台
推荐答案
显然,在PHP5.5.12的更高版本中已修复此问题。
我运行OP的代码(使用空方法),得到以下结果:
Static Time: 1.0153820514679 ms
Object Time: 1.100515127182 ms
编辑:八个月后发布...
看看Zend和社区是如何努力提高PHP性能的,这很有趣。
🐘PHP5.6
这里是与PHP 5.6.9
(ze 2.6)相同的基准:
Static Time: 0.97488021850586 ms
Object Time: 1.0362110137939 ms
Function Time: 0.96977496147156 ms
在一次运行中,"对象时间"甚至比静态时间更快,所以现在它们非常接近。更好的是,我们可以看到对象几乎和函数一样快!
🐘PHP7.0
我还编译了PHP 7.0 alpha 1
(ze 3.0),看到像PHP这样的快速语言(与其他动态语言相比,您可以看到here或here)如何一次又一次地进行优化,这是令人惊讶的:
Static Time: 0.33447790145874 ms
Object Time: 0.30291485786438 ms
Function Time: 0.2329089641571 ms
PHP7对基本功能进行了大幅优化,静态时间再次慢于实例/对象时间。
编辑,2015年10月一年后:PHP 7.0 RC5
现在,"静态时间"更快了。需要注意的一点是:标量类型提示(PHP7中的新功能)会带来很大的开销,它大约慢16%(类型提示不会使您的代码慢16%,当您的代码只由函数调用组成时,它的速度更慢;)在实际应用程序中,这可以忽略不计)。这样的开销可能看起来不合逻辑,但当您知道动态类型是PHP的核心时,它就不那么令人惊讶了。与其他更静态的语言相反,PHP中的类型提示意味着对Zend引擎的更多检查,而不是我们中的一些人所期望的少。在未来,我们可能会在这一点上得到更多的运行时优化(就像HHVM的运行时代码分析和JIT方法一样)。不要忘记,PHP7还很年轻,为这个版本所做的所有清理工作都允许在未来在功能和性能方面进行巨大的增强。
🐘HHVM
对HHVM 3.7.1
的测试仍然表明,HHVM很容易在该类型的基准测试中获胜,在这里您可以看到JIT编译的好处(JIT是PHP未来版本的"计划"特性,我们可能会在7.x或8.x分支中获得它。Zend had created a PoC, as an OpCache extension):
Static Time: 0.070882797241211 ms
Object Time: 0.23940300941467 ms
Function Time: 0.06760311126709 ms
对于HHVM,函数和静态方法的时间非常相似,这可能会让我们认为,在内部,这几乎是相同的事情(毕竟,静态方法非常类似于命名空间函数)。与其他实例相比,实例计时是"灾难性的"。这表明HHVM和ZE是非常不同的引擎。
结论?
不能保证其中一种做法(静态/实例)将永远保持较快的速度。使用软件设计方面似乎最好的方法,并将连贯的代码保留在现有应用程序中。
如果您可以选择,和/或如果您正在编写库等,那么您也许可以使用实例方法,它对DI环境更友好,并且给使用您的API的开发人员更多的控制权。
如果您只是提供实用程序函数(如NPM生态系统中的那些小程序包),则可以使用命名空间函数(但请注意PHP still doesn't have function autoloading,这意味着Composer can't lazy-load your library与PSR-0/4类似)
这篇关于静态方法的性能与函数的性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!