哪一个在php中迭代数组最快?或者是否存在另一个迭代数组的速度更快?
答案 0 :(得分:19)
即使存在任何差异,这种差异也会很小,根本不重要。
如果您对数据库进行了一次查询,那么与循环迭代结果相比,for
vs foreach
vs {{1}不会改变一件事 - 至少如果你有合理数量的数据。
所以,请使用:
在考虑这种微优化之前,还有很多其他事情你可以/应该优化。
如果你真的想要一些数字(即使它只是为了好玩),你可以制定一些基准并在实践中看到结果。
答案 1 :(得分:9)
对我来说,我根据这个来选择我的循环:
foreach
在迭代长度为(或可能)未知的数组时使用。
for
在遍历已设置长度的数组时,或者在需要计数器时使用。
while
在迭代数组时使用,其目的是查找或触发某个标记。
现在确实如此,你可以像使用count($ array)一样使用FOR循环之类的FOR循环......所以最终归结为你的个人偏好/风格。
答案 2 :(得分:4)
一般来说,这三个功能之间没有适用的速度差异。
提供基准测试结果,以证明用于迭代1 to 10,000
数组的不同方法的效率。
不同PHP版本的基准测试结果:https://3v4l.org/a3Jn4
while $i++: 0.00077605247497559 sec
for $i++: 0.00073003768920898 sec
foreach: 0.0004420280456543 sec
while current, next: 0.024288892745972 sec
while reset, next: 0.012929201126099 sec
do while next: 0.011449098587036 sec //added after terminal benchmark
while array_shift: 0.36452603340149 sec
while array_pop: 0.013902902603149 sec
考虑count
while
和for
$values = range(1, 10000);
$l = count($values);
$i = 0;
while($i<$l){
$i++;
}
$l = count($values);
for($i=0;$i<$l;$i++){
}
foreach($values as $val){
}
以下使用while
的示例演示了如何在迭代期间使用效率降低。
在功能上迭代数组并保持当前位置时;由于while
和next()
在迭代期间被调用,current()
的效率会降低。
while($val = current($values)){
next($values);
}
如果数组的当前位置不重要,您可以在迭代前调用reset()
或current()
。
$value = reset($values);
while ($value) {
$value = next($values);
}
do ... while
是一种可以使用的替代语法,也可以在迭代之前调用reset()
或current()
并将next()
调用移至结尾迭代。
$value = current($values);
do{
}while($value = next($values));
array_shift
也可以在迭代期间调用,但这会对性能产生很大的负面影响,因为array_shift
每次调用数组都会对数组进行重新索引。
while($values){
array_shift($values);
}
或者,array_reverse
可以在迭代之前与调用array_pop
一起调用。这样可以避免在调用array_shift
时重新编制索引的影响。
$values = array_reverse($values);
while($values) {
array_pop($values);
}
总之,while
,for
和foreach
的速度不应该是问题,而应该是为了维持数组的定位而在其中进行的操作。
答案 3 :(得分:2)
正确使用,虽然是最快的,因为它只能对每次迭代进行一次检查,将一个$ i与另一个$ max变量进行比较,并且在循环之前没有其他调用(除了设置$ max)或循环期间(除了$) i ++;这在任何循环语句中都是固有的。)
当你开始滥用它时(比如while(list ..))你当然会更好地使用foreach,因为每个函数调用都不会像foreach中包含的那样优化(因为那个是预先优化的) )。
即便如此,array_keys()为您提供与foreach相同的可用性,仍然更快。 除此之外,如果你进入二维阵列,一个自制的2d_array_keys将使你能够以更快的方式使用,然后可以使用foreach(只需尝试告诉第一个foreach中的下一个foreach,最后一个foreach有&lt; 2d_array_keys($ array)&gt;作为键---)。
此外,所有问题都与使用while的循环的第一项或最后一项有关($ i
while ($people_care_about_optimization!==true){
echo "there still exists a better way of doing it and there's no reason to use any other one";
}
答案 4 :(得分:1)
进行基准测试。
没有重大的“性能”差异,因为差异位于逻辑内部。
答案 5 :(得分:0)
请记住,将大量mysqli_result
预取到一个舒适的数组中会引发一个问题,即使用for
/ foreach
/ while
来循环该数组是否更好但是关于一个浪费大量内存的糟糕解决方案的问题是错误的。
所以不要这样做:
function funny_query_results($query) {
$results = $GLOBALS['mysqli']->query($query);
$rows = [];
while( $row = $results->fetch_object() ) {
$rows[] = $results;
}
return $rows;
}
$rows = funny_query_results("SELECT ...");
foreach($rows as $row) { // Uh... What should I use? foreach VS for VS while?
echo $row->something;
}
在简单mysql_result
中每while
个逐个获取的直接方式更加优化:
$results = $mysqli->query("SELECT ...");
while( $row = $results->fetch_object() ) {
echo $row->something;
}