人们喜欢优化。 它们容易理解,容易应用…… 但是不久前,在看Twig的拉动请求时,我读到了关于PHP中三元运算符性能的有趣讨论。
你知道下面哪个片段最快吗? 当然,它们做的是完全一样的事情。 //snippet 1
$tmp=isset($context['test'] )? $context['test'] : ';
//snippet 2
if(isset($context['test'] ) )。
$tmp=$context['test'];
} else {
$tmp=' ';
}
正确的答案是:
要看情况了。 大多数情况下,它们的速度是一样的。 没必要在意。 但是,如果$context['test']包含大量数据,snippet 2将比snippet 1快得多。
以下是我用于测试不同场景的代码: $ context=array (' test '=true );
//optionally文件- inthetestvaluewithlotsofdata
for($I=0; $i 100000; $i ) {
$context['test'][$i]=$i;
}
//youcanalsojustcreateabigstring
//$context=str_repeat (,1000000 );
//benchmark
$time=microtime(true );
for($I=0; $i 100; $i ) {
//the snippet of code to benchmark
$tmp=isset($context['test'] )? $context['test'] : ';
}
printf(time:%0.2d(n ),) microtime )- $time ) * 1000 );
请注意,这里的绝对性能数字是没有意义的。 我们只是想比较不同片段之间的速度。
在我的笔记本电脑上,snippet 1的运行时间超过2秒,snippet 2的运行时间约为0.05ms。 这是很大的不同! 但是,如果要测试的变量没有包含很多数据,速度就差不多了。
那么,为什么三元运算符在某些情况下会变慢呢? 为什么依赖于存储在测试变量中的值?
答案很简单:
三元运算符始终复制值,但if语句不复制值。 为什么? 由于PHP使用称为写入时副本的技术:因此在为变量赋值时,PHP在实际修改变量内容的副本之前不会创建。
编写语句(例如$tmp=$context['test'] ' )时,很少会出现:$tmp变量,而只是对$context['test']变量的引用。 所以很快。 但是,如果您想修改变量,PHP会将原始的:$tmp=$context['test'];
//the copy happens now
$tmp[]=true;
//copyalsohappensiftheoriginalvariablechanges
//$context['test'][]=true;
如上所述,三元运算符的速度与复制语句结果所需的时间直接相关,即使不严格需要也是如此。 复制100000个元素的数组需要时间。
如果使用的是PHP 5.3,有没有比使用新PHP更简单的方法?construct:是否表示我们的语言:$tmp=$context['test']? ' ';
但在性能方面,这种新结构具有与标准结构相同的缺点,有可能使PHP能够优化变量的存在情况。