while vs foreach vs for что быстрее в php
Один из самых важных и "узких" моментов, скорость работы массива. По массиву меню в процессе построения функции могут пробегать по многу раз, соответственно крайне важно чтоб этот момент работал на максимуме возможностей. давайте разберёмся всю ли правду пишут нам в интернете, какой массив работает быстрее while vs foreach vs for. Часть тестов не несут осмысленной нагрузки - ради интереса добавлены. Каждый тест перезапускался несколько раз.
Необходимо понимать, что тест имеет перекос в сторону обращения к двумерному массиву.
$a=array(
0=>array(0=>'top')
,1=>array(0=>'top')
,2=>array(0=>'top')
,3=>array(0=>'top')
,4=>array(0=>'top')
,5=>array(0=>'left')
,6=>array(0=>'left')
,7=>array(0=>'left')
,8=>array(0=>'left')
,9=>array(0=>'left')
);
в функциях function f1(){global $a; ..
1.
foreach($a as $v){
if($v[0]=='right'){}
}
2.
foreach($a as $k => $v){
if($v[0]=='right'){}
}
3.
for($i=0; $i<count($a); ++$i){
if($a[$i][0]=='right'){}
}
4.
$c=count($a);
for($i=0; $i<$c; ++$i){
if($a[$i][0]=='right'){}
}
5.
$c=count($a)-1;
for($i=$c; $i>0; --$i){
if($a[$i][0]=='right'){}
}
6.
reset($a);
while(list($k, $v) = each($a)){
if($v[0]=='right'){}
}
7.
reset($a);
while(list(, $v) = each($a)){
if($v[0]=='right'){}
}
8.
$i=0;
while($i<count($a)){
if($a[$i][0]=='right'){}
++$i;
}
9.
$i=0;
$c=count($a);
while($i<$c){
if($a[$i][0]=='right'){}
++$i;
}
10.
$i=count($a)-1;
while($i>-1){
if($a[$i][0]=='right'){}
--$i;
}
11.
$i=count($a)-1;
while($i>=0){
if($a[$i][0]=='right'){}
--$i;
}
Результаты тестирования скорости массивов в PHP
Компьютер:
№ | вызовов / функция | время | быстрее на |
1 | 1 / foreach($a as $v) | 0.000018 | +0.000006 с. | +33.33 % |
2 | 1 / foreach($a as $k => $v) | 0.000012 | 0.000000 с. | 0 % |
3 | 1 / for($i=0; $i<count($a); ++$i) | 0.000036 | +0.000024 с. | +66.67 % |
4 | 1 / $c=count($a); for($i=0; $i<$c; ++$i) | 0.000014 | +0.000002 с. | +14.29 % |
5 | 1 / $c=count($a)-1; for($i=$c; $i>0; --$i) | 0.000022 | +0.000010 с. | +45.45 % |
6 | 1 / reset($a); while(list($k, $v) = each($a)) | 0.000029 | +0.000017 с. | +58.62 % |
7 | 1 / reset($a); while(list(, $v) = each($a)) | 0.000035 | +0.000023 с. | +65.71 % |
8 | 1 / $i=0; while($i<count($a)) | 0.000028 | +0.000016 с. | +57.14 % |
9 | 1 / $i=0; $c=count($a); while($i<$c) | 0.000021 | +0.000009 с. | +42.86 % |
10 | 1 / $i=count($a)-1; while($i>-1) | 0.000013 | +0.000001 с. | +7.69 % |
11 | 1 / $i=count($a)-1; while($i>=0) | 0.000021 | +0.000009 с. | +42.86 % |
Сервер:
№ | вызовов / функция | время | быстрее на |
1 | 1 / foreach($a as $v) | 0.000014 | +0.000005 с. | +35.71 % |
2 | 1 / foreach($a as $k => $v) | 0.000009 | 0.000000 с. | 0 % |
3 | 1 / for($i=0; $i<count($a); ++$i) | 0.000035 | +0.000026 с. | +74.29 % |
4 | 1 / $c=count($a); for($i=0; $i<$c; ++$i) | 0.000012 | +0.000003 с. | +25 % |
5 | 1 / $c=count($a)-1; for($i=$c; $i>0; --$i) | 0.000020 | +0.000011 с. | +55 % |
6 | 1 / reset($a); while(list($k, $v) = each($a)) | 0.000023 | +0.000014 с. | +60.87 % |
7 | 1 / reset($a); while(list(, $v) = each($a)) | 0.000036 | +0.000027 с. | +75 % |
8 | 1 / $i=0; while($i<count($a)) | 0.000026 | +0.000017 с. | +65.38 % |
9 | 1 / $i=0; $c=count($a); while($i<$c) | 0.000021 | +0.000012 с. | +57.14 % |
10 | 1 / $i=count($a)-1; while($i>-1) | 0.000012 | +0.000003 с. | +25 % |
11 | 1 / $i=count($a)-1; while($i>=0) | 0.000023 | +0.000014 с. | +60.87 % |
В порядке возрастания
Компьютер:
№ | вызовов / функция | время | быстрее на |
2 | 1 / foreach($a as $k => $v) | 0.000012 | 0.000000 с. | 0 % |
10 | 1 / $i=count($a)-1; while($i>-1) | 0.000013 | +0.000001 с. | +7.69 % |
4 | 1 / $c=count($a); for($i=0; $i<$c; ++$i) | 0.000014 | +0.000002 с. | +14.29 % |
1 | 1 / foreach($a as $v) | 0.000018 | +0.000006 с. | +33.33 % |
9 | 1 / $i=0; $c=count($a); while($i<$c) | 0.000021 | +0.000009 с. | +42.86 % |
11 | 1 / $i=count($a)-1; while($i>=0) | 0.000021 | +0.000009 с. | +42.86 % |
5 | 1 / $c=count($a)-1; for($i=$c; $i>0; --$i) | 0.000022 | +0.000010 с. | +45.45 % |
8 | 1 / $i=0; while($i<count($a)) | 0.000028 | +0.000016 с. | +57.14 % |
6 | 1 / reset($a); while(list($k, $v) = each($a)) | 0.000029 | +0.000017 с. | +58.62 % |
7 | 1 / reset($a); while(list(, $v) = each($a)) | 0.000035 | +0.000023 с. | +65.71 % |
3 | 1 / for($i=0; $i<count($a); ++$i) | 0.000036 | +0.000024 с. | +66.67 % |
Сервер:
№ | вызовов / функция | время | быстрее на |
2 | 1 / foreach($a as $k => $v) | 0.000009 | 0.000000 с. | 0 % |
10 | 1 / $i=count($a)-1; while($i>-1) | 0.000012 | +0.000003 с. | +25 % |
4 | 1 / $c=count($a); for($i=0; $i<$c; ++$i) | 0.000012 | +0.000003 с. | +25 % |
1 | 1 / foreach($a as $v) | 0.000014 | +0.000005 с. | +35.71 % |
5 | 1 / $c=count($a)-1; for($i=$c; $i>0; --$i) | 0.000020 | +0.000011 с. | +55 % |
9 | 1 / $i=0; $c=count($a); while($i<$c) | 0.000021 | +0.000012 с. | +57.14 % |
6 | 1 / reset($a); while(list($k, $v) = each($a)) | 0.000023 | +0.000014 с. | +60.87 % |
11 | 1 / $i=count($a)-1; while($i>=0) | 0.000023 | +0.000014 с. | +60.87 % |
8 | 1 / $i=0; while($i<count($a)) | 0.000026 | +0.000017 с. | +65.38 % |
3 | 1 / for($i=0; $i<count($a); ++$i) | 0.000035 | +0.000026 с. | +74.29 % |
7 | 1 / reset($a); while(list(, $v) = each($a)) | 0.000036 | +0.000027 с. | +75 % |
Выводы
- Неожиданно foreach показал хороший результат..
- Не все циклы в обратном порядке работают быстрей.
- Count внутри цикла работает медленнее, везде об этом пишут - вычисляется на каждом шагу значение.
- Любые конструкции где php приходиться самому додумывать, обрабатывать пропуски - медленнее, так и здесь while(list(, $v)
- Больше или равно работает медленнее нежели меньше, поэтому >-1 писать выгоднее нежели >=0 итп.
- foreach($a as $k=>$v) быстрее чем foreach($a as $v)
Много где пишут, что foreach медленнее остальных циклов, при этом тесты проводят только через foreach($a as $v). Отдельно в следующий раз протестирую что же быстрей for, while на каком-нить синтетическом тесте без обращения к массиву.