[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: foreach() - альтернативы?
mrmaloy
Прошу прощения если не туда запостил, но хотелось бы услышать мнение знающих людей.
Я много слышал о том что foreach() очень медленный и его не желательно использовать.
Нужно ли его боятся как огня и выдумывать какой нибудь изврат типа:


$array = array('a','b','c','d','e');
$flag='0';
while($flag<=count($array)){
echo $array[$flag].'<br>';
$flag++;
}


или всетаки он не настолько страшный чтоб не использовать его вобще.




Спустя 41 минута, 19 секунд (19.06.2010 - 14:09) Kuzya написал(а):
Враньё. Фундоментальные конструкции php не такие медленные.
Используйте и ничего не бойтесь

Спустя 1 минута, 16 секунд (19.06.2010 - 14:11) SlavaFr написал(а):
в простом масиве можно и while использовать.
а как ты будеш с ассоциативным масивом работат?
вначале клучи от значений растягивать а потом в while проходить?

короче с асоциативным масивом ты извращайся как хочеш, а я буду foreach применять biggrin.gif

Спустя 11 минут, 39 секунд (19.06.2010 - 14:22) FatCat написал(а):
Цитата (mrmaloy @ 19.06.2010 - 14:28)
Я много слышал о том что foreach() очень медленный и его не желательно использовать.

Чтобы не слушать, а знать:
<?php
// Заполняем массив, запускаем таймер:
$test = array();
for($i=0;$i<10000;$i++)$test[] = $i;
list($usec, $sec) = explode(" ", microtime());
$timer_0 = ((float)$usec + (float)$sec);

// Тестируем for
$t = 0;
for($i=0;$i<10000;$i++)$t++;
list($usec, $sec) = explode(" ", microtime());
$timer_1 = ((float)$usec + (float)$sec);
echo "for: ".($timer_1-$timer_0);

// Тестируем while
while($i>=0)$i--;
list($usec, $sec) = explode(" ", microtime());
$timer_2 = ((float)$usec + (float)$sec);
echo "<br>while: ".($timer_2-$timer_1);

// Тестируем foreach
foreach($test as $t)$i++;
list($usec, $sec) = explode(" ", microtime());
$timer_3 = ((float)$usec + (float)$sec);
echo "<br>foreach: ".($timer_3-$timer_2);
?>

for: 0.0047619342804
while: 0.00278115272522
foreach: 0.00386881828308


Вывод: самый медленный - for; самый быстрый while; foreach по скорости средний.

Спустя 2 минуты, 5 секунд (19.06.2010 - 14:24) FatCat написал(а):
Для наглядности увеличил цикл до миллиона:
for: 0.47660279274
while: 0.272993087769
foreach: 0.389252901077

Спустя 23 минуты, 5 секунд (19.06.2010 - 14:47) Michael написал(а):
Имеются еще функции обхода массива:
reset(), next(), current() и подобные

Спустя 1 час, 9 минут, 41 секунда (19.06.2010 - 15:57) Nikitian написал(а):
Цитата (SlavaFr @ 19.06.2010 - 11:11)
а как ты будеш с ассоциативным масивом работат?

Как-то так:

$arr=array('a'=>'b','c'=>'d','e'=>'f');
$keys=array_keys($arr);
$values=array_values($arr);
for($i=0;$i<sizeof($arr);$i++){
echo'key: '.$keys[$i].', value: '.$values[$i].'<br />';
}


А вообще бред: разумеется используйте форич!

Спустя 1 час, 42 минуты, 51 секунда (19.06.2010 - 17:40) gzim9x написал(а):
Тони Хоар, Дональд Кнут: «Преждевременная оптимизация — корень всех зол»

Следующая версия PHP может запросто свести на нет ваш символический выигрыш в 0.00..7 мкс. Лучше сделайте код понятным.


Спустя 4 часа, 35 минут, 49 секунд (19.06.2010 - 22:16) SlavaFr написал(а):
@Nikitian, я то что вы в коде грамотно описали, в моем комментарии неграмотно словами обяснил. smile.gif

Спустя 3 дня, 18 часов, 42 минуты, 25 секунд (23.06.2010 - 16:58) mrmaloy написал(а):
Спасибо всем =)

Спустя 8 часов, 7 минут, 7 секунд (24.06.2010 - 01:05) dj_sedoy написал(а):
Цитата (FatCat @ 19.06.2010 - 11:22)
Чтобы не слушать, а знать

Ну бредовый тест. У меня, например, именно приведённый:

for: 0.0014290809631348
while: 0.00085091590881348
foreach: 0.0012710094451904

Разница более чем на порядок при таком теле цикла ни о чем не говорит?
Правильно smile.gif

А теперь попробуйте в цикле заполнять значения вашего непонятно для чего придуманного массива каким-нибудь значением, вычисляемым не оптимизируемым выражением, и тогда посмотрим, кто быстрее.

Но на самом деле, накладные расходы на каждую итерацию в цикле ооочень сильно зависят от задачи. И есть вполне определённые правила (даже аксиомы) при каких условиях какой цикл следует применять. Не знать этого стыдно должно быть.

Спустя 30 минут, 4 секунды (24.06.2010 - 01:35) FatCat написал(а):
Цитата (dj_sedoy @ 24.06.2010 - 02:05)
Разница более чем на порядок при таком теле цикла ни о чем не говорит?

Говорит о более быстрой машине. Но пропорции такие же: for оказался самым медленным.


Цитата (dj_sedoy @ 24.06.2010 - 02:05)
накладные расходы на каждую итерацию в цикле ооочень сильно зависят от задачи

Именно поэтому в тесте сделаны одинаковые минимальные задачи: инкремент.


Цитата (dj_sedoy @ 24.06.2010 - 02:05)
Не знать этого стыдно должно быть.

Я по образованию врач-психиатр и ни разу не программист. Если я начну рассуждать кому тут что должно быть стыдно, кто-то уйдет с парой ампул аминазина под шкурой пойдет регистрироваться на форуме, и я абсолютно точно уверен, что этот кто-то не я. user posted image

Спустя 2 часа, 22 минуты, 21 секунда (24.06.2010 - 03:58) kirik написал(а):
Я где-то уже с кем-то дискутировал на тему while/foreach.

Цитата (mrmaloy)
Я много слышал о том что foreach() очень медленный и его не желательно использовать.

Эт называется "слышу звон, да не знаю где он". Нет, foreach не медленный, и тесты FatCat это только доказывают. Отличие foreach, например от while заключается в том, что при проходе массива foreach проходит по копии оригинального массива, а while - по оригинальному.
PHP.NET так и говорит:
Цитата (http://ca3.php.net/manual/en/control-structures.foreach.php)
Unless the array is referenced, foreach operates on a copy of the specified array and not the array itself.

Тоесть на момент работы foreach в памяти находятся 2 одинаковых массива: один оригинальный, второй с которым работает foreach.
Отсюда можно сделать вывод, что если:
- большой массив
- мало памяти на сервере
= использовать while

ЗЫ. тему бы закрепить, что-ли..

Спустя 1 час, 32 секунды (24.06.2010 - 04:58) dj_sedoy написал(а):
Цитата (FatCat @ 23.06.2010 - 22:35)
Именно поэтому в тесте сделаны одинаковые минимальные задачи: инкремент.

И тем самым заменены ампулы аминазина на физраствор.
Я имею ввиду, что в зависимости от параметров компиляции любой из этих циклов может выродиться в банальное присваивание, а в результате мы получим результаты, где (даже стыдно сказать) один цикл выигрывает у другого.
И я как бы тоже не строитель, поэтому на формах стоматологов не рассуждаю, как бороться с малинно-земляничным долгоносиком smile.gif
rolleyes.gif

Спустя 17 минут, 17 секунд (24.06.2010 - 05:16) dj_sedoy написал(а):
Цитата (kirik @ 24.06.2010 - 00:58)
Отсюда можно сделать вывод, что если:
- большой массив
- мало памяти на сервере

= используем указатель на массив, ибо итераторы - тоже крайне полезная вещь.

Спустя 4 часа, 21 минута, 15 секунд (24.06.2010 - 09:37) kirik написал(а):
dj_sedoy
Зачем же все усложнять?

Спустя 4 дня, 2 часа, 31 минута, 49 секунд (28.06.2010 - 12:09) linker написал(а):
Люди, вы чего? ohmy.gif ohmy.gif ohmy.gif
function foo($Item, $Key)
{
echo "$Key : $Item";
}
$Array = array(1, 2, 3, 4);
array_walk($Array, 'foo');

Спустя 18 часов, 32 минуты, 48 секунд (29.06.2010 - 06:41) kirik написал(а):
linker
с foreach/while/for на одну строку меньше выйдет wink.gif

Спустя 1 час, 59 минут, 4 секунды (29.06.2010 - 08:40) linker написал(а):
kirik, а вы зря гонитесь за количество строк, главное не как вы кратко записано, а насколько оно быстро работает. Вы на сях напишете 1 строку
cout << "Hello world";
я на ассемблере напишу 50 строк, но эти 50 строк будут работать быстрее, чем одна ваша.
Если уж вам так нравится, то
function foo($Item, $Key) { echo "$Key : $Item"; }
$Array = array(1, 2, 3, 4);
array_walk($Array, 'foo');

Спустя 3 минуты, 29 секунд (29.06.2010 - 08:44) tomash написал(а):
linker
Вы зря гонитесь за скоростью wink.gif
Пока вы напишите программу на ассемблере, я напишу 5 программ на С))) Все должно быть оптимально. И зависит от задачи

Спустя 17 минут, 53 секунды (29.06.2010 - 09:02) linker написал(а):
tomash
Мой пример к тому, что количество строк не всегда имеет значение, естественно никто не отменяет здравый смысл и практичность. В промышленном масштабе приходится жертвовать многим, но эта жертва должна быть в разумных пределах. Вместо того чтобы плодить бесчисленное количество циклов, разрабы php для вас же сделали такие удобные функции для работы с массивами. Так как тема "замена foreach", то мой пример очень наглядно показывает как можно в некоторых случаях избавиться от вездесущих циклов.

Спустя 34 минуты (29.06.2010 - 09:36) Guest написал(а):
Цитата
array_walk

- просто пробег массива, а в циклах как правило идет работа также с внешними помимо только массива данными. Сумму например посчитать. Используя array_walk это надо делать или через глобальные переменные или передавая через ссылку переменные. Для всех возможных случаев - замусоривание проекта "очень полезными" функциями - гомнокодинг.

Так что:

linker, ты чего ? ohmy.gif ohmy.gif ohmy.gif

Спустя 31 минута, 52 секунды (29.06.2010 - 10:08) linker написал(а):
Guest
а вы случайно не встречали такую конструкцию:
$Array = array(1, 5, 10, 4, 1, 40);
echo array_reduce($Array, 'Sum', 0);
function Sum($Value, $Result)
{
$Value += $Result;
return $Value;
}
результатом которой будет "61" (т.е. сумма всех элементов массива)?

Спустя 37 минут, 37 секунд (29.06.2010 - 10:45) kirik написал(а):
Цитата (linker @ 29.06.2010 - 01:02)
мой пример очень наглядно показывает как можно в некоторых случаях избавиться от вездесущих циклов

Ага.. и наплодить кучу непонятных, одноразовых функций..

Цитата (linker @ 29.06.2010 - 00:40)
главное не как вы кратко записано, а насколько оно быстро работает

Гм) А вот тесты мы любим))
$arr = range(0, 100002);

$t1 = microtime(1);
function foo(&$v, $k) {
$v++;
}
array_walk($arr, 'foo');
$r1 = round(microtime(1) - $t1, 4);

$t2 = microtime(1);
foreach($arr as $k => &$v) {
$v++;
}
$r2 = round(microtime(1) - $t2, 4);

echo 'Вариант с array_walk: ' . $r1 . '<br />Вариант с циклом: ' . $r2;
// Вариант с array_walk: 0.0961
// Вариант с циклом: 0.0338

Вроде все правильно.. Получается мало того, что на строчку короче, так еще и в 3 раза быстрее! smile.gif

Цитата (linker @ 29.06.2010 - 01:02)
разрабы php для вас же сделали такие удобные функции для работы с массивами

Чтоже выходит.. Не все что накодили разработчики оптимальнее и быстрее "тупого" решения wink.gif

Спустя 27 минут, 8 секунд (29.06.2010 - 11:12) linker написал(а):
kirik
Вы что-то путаете, функций может быть одна, а вот массивов, с которыми надо делать одни и те же операции, куча. Я же сказал, во всем должна быть разумность, необходимость и практичность, ну и как замена foreach очень подходит.

p.s. Со скоростью, я конечно же, обмишулился, спору нет.
p.s.p.s. Как минимум у этих же разработчиков, без знания, понимания и умения пользоваться этими функциями, не получите соответствующий сертификат smile.gif

Спустя 12 часов, 28 минут, 29 секунд (29.06.2010 - 23:41) kirik написал(а):
Цитата (linker @ 29.06.2010 - 03:12)
Вы что-то путаете, функций может быть одна, а вот массивов, с которыми надо делать одни и те же операции, куча.

Согласен, все зависит от задач. Но если требуется "прозрачность" кода, то ИМХО использование цикла будет понятнее.

Спустя 8 часов, 14 минут, 37 секунд (30.06.2010 - 07:56) linker написал(а):
kirik, согласен.


_____________
<td></td>...<td></td>...<td></td>... тихо стучали колеса поезда в ночной тишине.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2025 Invision Power Services, Inc.