Nig*_*awk 10 php performance foreach
foreach(explode(',' $foo) as $bar) { ... }
Run Code Online (Sandbox Code Playgroud)
VS
$test = explode(',' $foo);
foreach($test as $bar) { ... }
Run Code Online (Sandbox Code Playgroud)
在第一个例子中,它explode是$foo每次迭代的字符串,还是PHP将它保存在内存中,在其自己的临时变量中爆炸?从效率的角度来看,创建额外变量$test或两者都相等是否有意义?
Wis*_*guy 22
我可以做出有根据的猜测,但让我们尝试一下吧!
我认为有三种主要方法可以解决这个问题.
我的假设:
这是我的测试脚本:
<?php
ini_set('memory_limit', '1024M');
$listStr = 'text';
$listStr .= str_repeat(',text', 9999999);
$timeStart = microtime(true);
/*****
* {INSERT LOOP HERE}
*/
$timeEnd = microtime(true);
$timeElapsed = $timeEnd - $timeStart;
printf("Memory used: %s kB\n", memory_get_peak_usage()/1024);
printf("Total time: %s s\n", $timeElapsed);
Run Code Online (Sandbox Code Playgroud)
以下是三个版本:
1)
// explode separately
$arr = explode(',', $listStr);
foreach ($arr as $val) {}
Run Code Online (Sandbox Code Playgroud)
2)
// explode inline-ly
foreach (explode(',', $listStr) as $val) {}
Run Code Online (Sandbox Code Playgroud)
3)
// tokenize
$tok = strtok($listStr, ',');
while ($tok = strtok(',')) {}
Run Code Online (Sandbox Code Playgroud)

看起来有些假设被证明是错误的.你不爱科学吗?:-)
explode()没有预先分配内联时,由于某种原因,它会慢一点.strtok()每次迭代进行函数调用.更多关于此的信息.就函数调用的数量而言,explode()真正的顶级令牌化.O(1) vs O(n)
我在图表中添加了一个奖励,我在循环中使用函数调用运行方法1).我用过strlen($val),认为这将是一个相对类似的执行时间.这是有争议的,但我只是想提出一个普遍的观点.(我只跑了strlen($val),而忽视它的输出.我并没有把它分配给什么,对于一个任务将是一个额外的时间成本.)
// explode separately
$arr = explode(',', $listStr);
foreach ($arr as $val) {strlen($val);}
Run Code Online (Sandbox Code Playgroud)
从结果表中可以看出,它成为三者中最慢的方法.
这很有趣,但我的建议是做任何你认为最易读/可维护的事情.只有当你真正处理一个非常大的数据集时,你才会担心这些微观优化.