| « MSSQL - убожество | Концентратор доступа @Net ATLAC (beta7) - динамика нагрузки (дополнено 01.03.2010) » |
Быстрый и легкий foreach со ссылкой на элемент массива в PHP
Меткие заметки, Прочее ITМногие начинающие PHP-шники критикуют foreach за огромный расход памяти при простых проходах, низкую скорость копирования массива для прохода, невозможность менять элементы массива в проходе, и прочее блаблабла.
И почему-то при этом все забывают про одну замечательную конструкцию:
foreach ($array as $key => &$value)
{
# your code here (you can even modify $value and it'll get into original array)
} unset($value);
Прелесть этой конструкции очевидна:
1) никакого копирования массива для прохода не выполняется
2) соответственно, нет накладных расходов на копирование по CPU и памяти
3) можно изменять элементы массива не по $array[$key] = 'xyzzy', а прямо по $value = 'xyzzy'
unset в конце нужен для того, чтобы после при выполнении $value = 'mydata' не получить случайное изменение последнего элемента массива по ссылке в $value
Трекбек адрес этой записи
URL трекбека (щелкните правой кнопкой мыши и скопируйте ссылку)
foreach($myArray as &$value) {
# code here
}
тоже работает.
При применении ссылки отпадает надобность возвращать ещё и ключ во многих случаях
foreach ($myArray as &$value){
# code here
} unset($value);
иначе при неудачном стечении обстоятельств потом можно будет долго и весело искать неожиданные грабли с неверным значением в массиве.
Основной смысл поста в том, что ключ зачастую не нужен и без него всё вполне будет работать.
"PHP is smart enough not to copy the actual variable container when it is not necessary."
http://ru2.php.net/manual/en/features.gc.refcounting-basics.php
Делал практические тесты, которые показывали одинаковые результаты по времени, когда используется ссылка и когда её нет.
Надо будет протестировать еще несколько раз.
Правда, у меня всегда достаточно специфичная обработка, очень часто - с вызовами функций над элементами массива.
Возможность изменения массива в проходе тоже лишней не бывает.
А так я тестировал кажется на массиве из 100к элементов, выполняя в цикле несложные операции (не меняя $value, чтобы было так, как в мануале). И так, и так получалось 3 с копейками секунды.