Внешний вид сайта:

PHP: правильный перебор массивов

Довольно часто, в учебной литературе для перебора массивов предлагают следующую конструкцию. На первый взгляд все хорошо, но использовать такой код крайне не желательно.
$array = range(0, 999999);
$time_start = microtime(TRUE);
for($i=0; $i<count($array); $i++){}
echo microtime(TRUE)-$time_start;

Дело в том, что на каждой итерации цикла, а если говорить точнее, при проверке условия, будет вызываться функция count(). Можно конечно видоизменить код следуюшим образом:

$array = range(0, 999999);
$time_start = microtime(TRUE);
for($i=0, $arr_l=count($array); $i<$arr_l; $i++){}
echo microtime(TRUE)-$time_start;   

Второй вариант будет работать быстрее. В моем случае разница составила 0.3 секунды. Но опять же получается как-то некрасиво, с дополнительной переменной, что не есть хорошо. Спрашивается, зачем вообще использовать цикл for, если в php существует замечательный цикл foreach? Который, кстати, специально предназначен для перебора массивов и объектов.

$array = range(0, 999999);
$time_start = microtime(TRUE);
foreach($array as $e){}
echo microtime(TRUE)-$time_start;

К тому же последний вариант, работает еще немного быстрее, чем предыдущий. Не значительно, но быстрее где-то на 0.01 секунды.

Так почему, некоторые, до сих пор продолжают использовать цикл for? Скорее всего дело в том, что неопытные программисты тут же зададут вопрос: "Мужик! Это конечно хорошо, но в последнем случае мы не можем изменять элементы массива". И опять же, это является очень большим заблуждением. Рассмотрим простой пример, переберем все элементы масива и умножим их на 2. Пожалуйста:

$array = range(0, 999999);
$time_start = microtime(TRUE);
foreach($array as &$e){
    $e *= 2;
}
unset($e);
echo microtime(TRUE)-$time_start;

Здесь разница состоит лишь в том, что переменная $e будет являться ссылкой на значение элемента массива. Ну и не забываем удалять ее после выполнения цикла с помощью функции unset(). Делать это нужно обязательно.

И напоследок, еще один пример, где действительно может пригодится конструкция for. Здесь речь идет о случае, когда нужно перебрать элементы массива с конца. И опять, многие источники предлагают делать так:

$array = range(0, 999999);
$time_start = microtime(TRUE);
for(end($array); $k=current($array); prev($array)){
    $array[$k] *= 2;
}
echo microtime(TRUE)-$time_start;

Хотя можно просто, без наворотов:

$array = range(0, 999999);
$time_start = microtime(TRUE);
for($i=count($array); $i>=0; $i--){
    $array[$i] *= 2;
}
echo microtime(TRUE)-$time_start;

Время выполнения первого скрипта 0.856 сек, второго — 0.157 сек (быстрее в 5 раз!). Какой из них лучше решать вам.

Комментарии

Нет комментариев. Ваш будет первым!