【问题标题】:Is there a performance penalty for accessing count($array) each time in a foreach loop?在 foreach 循环中每次访问 count($array) 是否有性能损失?
【发布时间】:2014-01-25 21:39:35
【问题描述】:

我在 SO 偶然发现了“Find the last element of an array while using a foreach loop in PHP”这个问题。

comments 用户“johndodo”声称在 foreach 循环中每次访问 count($array) 不会造成性能损失。

"[...] 在 PHP 中,每次访问 count($arr) 都没有性能损失。原因是项目计数在内部保存为数组标题中的特殊字段,而不是在--飞。[...]”

所以:

foreach ($array as $line) {
    $output .= '    ' . $line;
    // add LF if not the last line
    if ($array[count($array) - 1] != $line) {
        $output .= "\n";
    }
}

应该和以下一样快:

$arrayLen = count($array) - 1;
foreach ($array as $line) {
    $output .= '    ' . $line;
    // add LF if not the last line
    if ($array[$arrayLen] != $line) {
        $output .= "\n";
    }
}

好吧,事实并非如此。在进行分析时,可以看出在第一个示例中花费了大量时间来执行count()是因为用户提出的声明没有实际意义,还是因为我们在紧凑的 foreach 循环中调用了一个函数?

【问题讨论】:

  • 因为您正在为循环的每次迭代调用一个函数。这是创建 for 循环时特别常见的错误:即 for($i = 0; $i
  • 是的,假设数据集很大,带有$arrayLen = count(); 的第二个版本要好得多。并且保持一般的良好做法。
  • 找出答案的一个好方法是将这个循环放入另一个循环中(比如说 10,000 次迭代),看看它需要多长时间......
  • 这是一个函数调用的开销:但是数组结构在内部包含一个计数值,所以它不需要每次遍历数组计算每个元素......即使这样,性能更大的数组差异很明显
  • 你可以使用 implode() 而不是循环进行测试,但要注意内存开销

标签: php arrays performance foreach


【解决方案1】:

“johndodo”所掌握的是,正如 Mark Ba​​ker 在 cmets 中很好地指出的那样,数组结构在内部包含一个计数值,因此它不需要每次遍历数组来计算每个元素。

“johndodo”的说法没有考虑的是,在循环中调用函数时会产生大量开销。

【讨论】:

  • 这句话已经过时了,没有人再使用这些架构了。而在 PHP 中,几乎所有东西都是昂贵的,甚至读取一个变量(是的,显然函数调用更昂贵......)
  • 为什么投反对票? @Karoly 我的观点是,无论架构或语言如何,函数调用都很昂贵。它们是如此昂贵,以至于应该不惜一切代价避免在循环中调用琐碎的函数。在 C/C++ 中,我们有 inline 关键字,以便我们可以进行内联扩展,但是在 PHP 中没有这样的功能,所以我们别无选择,只能手动排列那些琐碎的函数,牺牲代码的清洁度并复制我们的源代码。无论如何,也许我应该只编辑引用(除非反对者认为其余的答案也没有用)?
  • 现代编译器会在有意义的情况下内联小函数调用。因此,该报价与今天无关。注意:stackoverflow.com/questions/5971736/c-inline-function
  • @KarolyHorvath 是的,但是 PHP(或者说它是解释器)不支持内联扩展,所以引用在 PHP 的上下文中至少有一些优点。
猜你喜欢
  • 1970-01-01
  • 2014-04-01
  • 2018-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-21
  • 1970-01-01
相关资源
最近更新 更多