Прежде всего, я понимаю, что в 90% приложений разница в производительности совершенно не имеет значения, но мне просто нужно знать, какая из них быстрее. Это и...
Информация, доступная в настоящее время в сети, путается. Многие люди говорят, что foreach - это плохо, но технически это должно быть быстрее, поскольку предполагается упростить запись обхода массива с использованием итераторов. Итераторы, которые, опять же, предполагают, что они быстрее, но в PHP также, по-видимому, мертвы медленно (или это не проблема PHP?). Я говорю о функциях массива: next() prev() reset() и т.д. Ну, если они являются четными функциями, а не одной из тех функций языка PHP, которые выглядят как функции.
Чтобы сузить это немного: мне не интересно перемещаться по массивам с шагом более чем на 1 (никаких отрицательных шагов, т.е. обратной итерации). Меня также не интересует обход к и от произвольных точек, всего от 0 до длины. Я также не вижу манипуляции массивами с более чем 1000 ключами, происходящими на регулярной основе, но я вижу, что массив проходит несколько раз в логике приложения! Также, как и для операций, в основном, только строковые манипуляции и эхо-сигналы.
Вот несколько ссылочных сайтов:
http://www.phpbench.com/
http://www.php.lt/benchmark/phpbench.php
То, что я слышу повсюду:
-
foreach
медленный, и, следовательно,for
/while
быстрее - PHPs
foreach
копирует массив, в котором он итерации; чтобы сделать это быстрее, вам нужно использовать ссылки - :
$key = array_keys($aHash); $size = sizeOf($key);
быстрее, чем
for ($i=0; $i < $size; $i++)foreach
Вот моя проблема. Я написал этот тест script: http://pastebin.com/1ZgK07US и независимо от того, сколько раз я запускаю script, я получаю что-то вроде этого:
foreach 1.1438131332397
foreach (using reference) 1.2919359207153
for 1.4262869358063
foreach (hash table) 1.5696921348572
for (hash table) 2.4778981208801
Короче:
-
foreach
быстрее, чемforeach
со ссылкой -
foreach
быстрее, чемfor
-
foreach
быстрее, чемfor
для хеш-таблицы
Может кто-нибудь объяснить?
- Я делаю что-то неправильно?
- Является ли ссылка PHP foreach ссылкой действительно имеющей значение? Я имею в виду, почему бы не скопировать его, если вы пройдете по ссылке?
- Что эквивалентный код итератора для оператора foreach; Я видел несколько в сети, но каждый раз, когда я тестирую их, время уходит; Я также протестировал несколько простых конструкций итераторов, но никогда не получал даже достойных результатов. Являются ли итераторы массивов на PHP просто ужасными?
- Существуют ли более быстрые способы/методы/конструкции для итерации, кроме массива, отличного от FOR/FOREACH (и WHILE)?
PHP версия 5.3.0
Изменить: ответ С помощью людей здесь я смог собрать ответы на все вопросы. Я приведу их здесь:
- "Я что-то делаю неправильно?" Консенсус, похоже, таков: да, я не могу использовать эхо в тестах. Лично я до сих пор не вижу, как эхо - это некоторая функция со случайным временем выполнения или как любая другая функция каким-то образом отличается от того, что и способность этого script просто генерировать точные результаты foreach лучше всего трудно объяснить, хотя просто "вы используете эхо" (ну, что я должен использовать). Однако я соглашаюсь, что тест должен быть сделан с чем-то лучшим; хотя идеальный компромисс не приходит в голову.
- "Является ли ссылка PHP foreach ссылкой действительно меняющейся? Я имею в виду, почему она не копирует ее, если вы пройдете по ссылке?" ircmaxell показывает, что да, дальнейшее тестирование, похоже, доказывает, что в большинстве случаев ссылка должна быть быстрее - хотя, учитывая мой вышеприведенный фрагмент кода, определенно это не значит все. Я принимаю, что проблема, вероятно, слишком неинтуитивная, чтобы беспокоиться на таком уровне и требовать чего-то экстремального, такого как декомпиляция, чтобы фактически определить, что лучше для каждой ситуации.
- "Какой эквивалентный код итератора для оператора foreach, я видел несколько в сети, но каждый раз, когда я проверяю их, время идет, и я тестировал несколько простых конструкций итератора, но, похоже, даже достойные результаты - итераторы массива на PHP просто ужасны?" ircmaxell дал ответ ниже; хотя код может быть действителен только для версии PHP >= 5
- "Существуют ли более быстрые способы/методы/конструкции для итерации, если массив, отличный от FOR/FOREACH (и WHILE)?" Спасибо, Гордон за ответ. Использование новых типов данных в PHP5 должно давать либо повышение производительности, либо увеличение памяти (любой из которых может быть желательным в зависимости от вашей ситуации). В то время как скорость мудрее многих новых типов массивов не кажется лучше, чем array(), splpriorityqueue и splobjectstorage выглядят значительно быстрее. Ссылка, предоставленная Гордоном: http://matthewturland.com/2010/05/20/new-spl-features-in-php-5-3/
Спасибо всем, кто пытался помочь.
Я, скорее всего, придерживаюсь foreach (версия без ссылки) для любого простого обхода.