foreach(explode(',' $foo) as $bar) { ... }
против
$test = explode(',' $foo); foreach($test as $bar) { ... }
В первом примере он explode
строку $foo
для каждой итерации или PHP хранит ее в памяти взорван в своей временной переменной? С точки зрения эффективности, имеет ли смысл создавать дополнительные переменные $test
или они почти равны?
Я мог бы дать обоснованное предположение, но давайте попробуем !
Я подумал, что есть три основных способа приблизиться к этому.
Мои гипотезы:
Вот мой тестовый скрипт:
<?php ini_set('memory_limit', '1024M'); $listStr = 'text'; $listStr .= str_repeat(',text', 9999999); $timeStart = microtime(true); /***** * {INSERT LOOP HERE} */ $timeEnd = microtime(true); $timeElapsed = $timeEnd - $timeStart; printf("Memory used: %s kB\n", memory_get_peak_usage()/1024); printf("Total time: %ss\n", $timeElapsed);
И вот три версии:
1)
// explode separately $arr = explode(',', $listStr); foreach ($arr as $val) {}
2)
// explode inline-ly foreach (explode(',', $listStr) as $val) {}
3)
// tokenize $tok = strtok($listStr, ','); while ($tok = strtok(',')) {}
Похоже, некоторые предположения были опровергнуты. Разве вы не любите науку? 🙂
explode()
inline без предварительного назначения, по какой-то причине это немного медленнее. strtok()
каждая итерация. Подробнее об этом ниже. С точки зрения количества вызовов функций, explode()
действительно набирает токенизацию. O (1) vs O (n)
Я добавил бонус к диаграмме, где я запускаю метод 1) с вызовом функции в цикле. Я использовал strlen($val)
, считая, что это будет относительно аналогичное время выполнения. Это подлежит обсуждению, но я только пытался сделать общий вывод. (Я только побежал strlen($val)
и проигнорировал его вывод. Я не присваивал его никому, потому что назначение было бы дополнительной временной стоимостью.)
// explode separately $arr = explode(',', $listStr); foreach ($arr as $val) {strlen($val);}
Как видно из таблицы результатов, она становится самым медленным методом из трех.
Это интересно знать, но мое предложение состоит в том, чтобы делать все, что вы считаете наиболее читаемым / поддерживаемым. Только если вы действительно имеете дело с значительно большим набором данных, вы должны беспокоиться об этих микро-оптимизации.
В первом случае PHP взрывает его один раз и сохраняет его в памяти.
Влияние создания другой переменной или другого пути было бы незначительным. PHP Interpreter должен будет поддерживать указатель на местоположение следующего элемента, независимо от того, определены они пользователем или нет.
С точки зрения памяти это не изменит, потому что PHP использует копию для концепции записи .
Кроме того, я лично предпочел бы первый вариант – это строка меньше, но не менее читаемая (imho!).
Эффективность в каком смысле? Управление памятью или процессор? Процессор не повлиял бы на память – вы всегда можете делать $foo = explode(',', $foo)