为啥 count 比 $count 差

Posted

技术标签:

【中文标题】为啥 count 比 $count 差【英文标题】:Why count is bad than $count为什么 count 比 $count 差 【发布时间】:2011-08-06 09:27:46 【问题描述】:

我只是在查看不同问题的答案以了解更多信息。我看到一个answer 说用php写是不好的做法

for($i=0;$i

它说在循环中调用计数函数会降低代码的速度。 cmets 对这个问题的讨论并不清楚。我想知道为什么这不是好的做法。这样做的替代方法应该是什么?

【问题讨论】:

【参考方案1】:

你应该这样做:

$count = count($array);
for($i=0;$i<$count;$i++)...

这样做的原因是,如果您将 count($array) 放在 for 循环中,那么每次迭代都必须调用 count 函数,这会减慢速度。

但是,如果将计数放入变量中,它是一个静态数字,不必每次都重新计算。

【讨论】:

【参考方案2】:

我听说医生手术中的一个数据库使用软件就犯了这个错误。它用大约 100 条记录进行了测试,一切正常。在几个月内,它处理了数百万条记录并且完全无法使用,需要几分钟才能加载结果。根据上面的答案替换了代码,并且效果很好。

换一种方式来考虑,一个相当强大的专用服务器并没有做太多其他事情,它会花费大约 1 纳秒来完成 count($array)。如果您有 100 个 for 循环,每个循环计算 1,000 行,那么这只有 0.0001 秒。

但是,每次页面加载需要 100,000 次计算。将其扩展到 1,000,000 个用户(谁不想拥有 100 万个用户?)... 加载 10 个页面,现在您有 1,000,000,000,000(1 万亿)次计算。这会给服务器带来很大的负担。您的处理器花费 1,000 秒(约 16.5 分钟)来运行该代码。

现在增加机器处理代码所花费的时间、数组中的项目数以及代码中 for 循环的数量……您实际上是在谈论数万亿个进程和数小时的只需先将结果存储在变量中即可避免处理时间。

【讨论】:

【参考方案3】:

对于每次迭代,PHP 都会检查循环的那一部分(条件),看它是否应该继续循环,每次检查时,它都会计算数组的长度。

缓存该值的简单方法是...

for($i=0,$count=count($array);$i<$count;$i++)  ... 

在小循环中可能没有必要,但在迭代数千个项目时可能会产生巨大的差异,并且取决于条件中的函数调用(以及它如何确定其返回值)。

这也是为什么您应该尽可能使用foreach() ... 的原因,它使用数组副本上的迭代器来循环集合,您不必担心缓存循环的条件。

【讨论】:

你的意思是foreach循环保留了数组的副本?对不起,我没看懂。 @Awais 是的,在迭代它之前,它会创建一个副本,重置它并推进它的指针而不是原始指针。 很好,但是如果我们有非常大的数组,那么循环同时拥有一个副本和一个原始数组是一个可行的解决方案吗? @Awais 尝试并分析它,如果它成为您应用程序的瓶颈,您可以切换到普通的for 循环。【参考方案4】:

这不是一个好习惯,因为正如所写,每次循环都会调用count($array)。假设您不会在循环中更改数组的大小(这本身就是一个可怕的想法),此函数将始终返回相同的值,并且重复调用它是多余的。

对于短循环,差异可能不会很明显,但最好还是调用一次函数并在循环中使用计算值。

【讨论】:

以上是关于为啥 count 比 $count 差的主要内容,如果未能解决你的问题,请参考以下文章

为啥从大表中查询 COUNT() 比 SUM() 快得多

select count(*),count,count(name)哪个性能好,为什么

执行countcount(*) 与 count(列名) 到底有什么区别?

count 与 count(*) 比较

SQL中 count(*)和count的对比,区别

countcount(*)和count(指定字段)之间的区别