作为项目的一部分,我遇到了这种情况,在循环内部,我存储函数返回的值。 这恰好是应用程序的瓶颈,大型数组将需要永远处理。
对我而言,任务应该没有理由让人难以置信的缓慢表现。 另一方面,相同的函数调用,返回时没有赋值,可以提供更好的性能。
你能解释一下为什么第一个循环要慢得多吗?
Output:
First took 1.750 sec.
Second took 0.003 sec.
class one {
private $var;
public function __construct() {
$this->var = array();
}
public function saveIteration($a) {
$this->var[] = $a;
return $this->var;
}
public function getVar() {
return $this->var;
}
}
$one = new one();
$time_start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
$res = $one->saveIteration($i);
}
echo "First took " . number_format(microtime(true) - $time_start, 3) . " sec.";
$time_start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
$one->saveIteration($i);
}
$res = $one->getVar();
echo "<br>Second took " . number_format(microtime(true) - $time_start, 3) . " sec.";
答案 0 :(得分:1)
根据http://php.net/manual/en/functions.returning-values.php#99660,数组返回值不通过引用传递,而是按值传递。这意味着创建了一个数组的副本(至少,当你再次更改它时),这反过来需要时间来实际创建副本(分配内存,memcopy数据)。
答案 1 :(得分:0)
@Jakumi提出了一个很好的观点。由于在分配时必须复制值,因此在第一个循环中需要10,000个额外的操作和更多的内存。
两个循环之间的差异实际上远大于测试显示。如果在两个测试之间,您重置为:
,那么您的比较会更公平unset($one); $one = new one();
在当前的测试中,第二个循环正在执行,同时仍然保留内存中第一个循环的大数组,因此结果不是独立的。见this modification
答案 2 :(得分:0)
这可能与您创建10.000阵列的事实有关;每次将 new 数组的元素数量增加1个元素。
我猜你在循环中时局部变量本身没有被释放;因此,我继续前进尝试使用未设置释放它,结果非常接近。
我知道这不是一个现实世界的例子;但是在你的代码中,如果你有类似的东西,你可以通过在完成它后释放(取消设置)局部变量来逃脱它
这是你的测试代码:
class one {
private $var;
public function __construct() {
$this->var = array();
}
public function saveIteration($a) {
$this->var[] = $a;
return $this->var;
}
public function getVar() {
return $this->var;
}
}
$one = new one();
$time_start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
$res = $one->saveIteration($i);
unset($res);
}
echo "First took " . number_format(microtime(true) - $time_start, 3) . " sec.".PHP_EOL;
$time_start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
$one->saveIteration($i);
}
$res = $one->getVar();
echo "Second took " . number_format(microtime(true) - $time_start, 3) . " sec.".PHP_EOL;
注意:我唯一修改的是在第一个例子中添加未设置
结果: