Я мог бы сделать обоснованное предположение, но давайте попробуем !
Я подумал, что есть три основных способа приблизиться к этому.
- взорваться иприсваивать перед входом в цикл
- взрываться внутри цикла, нет присваивания
- строка токенизации
Мои гипотезы:
- вероятно потребляют большепамять из-за присваивания
- , вероятно, идентична # 1 или # 3, не уверен, что
- , вероятно, и быстрее, и намного меньше занимаемой памяти
Подход
Вот мой тестовый скрипт:
<?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: %s s\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()
встраиваете без предварительного назначения, это немного медленнеепо какой-то причине. - Удивительно, но токенизация немного на медленнее , чем явная итерация объявленного массива.Работая в таком небольшом масштабе, я полагаю, что это связано с накладными расходами стека вызовов при вызове функции для
strtok()
каждой итерации.Подробнее об этом ниже.
С точки зрения количества вызовов функций, explode()
действительно возглавляет токенизацию. O (1) против O (n)
Я добавил бонус на график, где я запускаю метод 1) с помощью вызова функции в цикле.Я использовал strlen($val)
, думая, что это будет относительно похожее время выполнения.Это подлежит обсуждению, но я только пытался сделать общее замечание.(Я только набрал strlen($val)
и проигнорировал его вывод. Я не присвоил его чему-либо, так как назначение было бы дополнительными временными затратами.)
// explode separately
$arr = explode(',', $listStr);
foreach ($arr as $val) {strlen($val);}
Как вы можетекак видно из таблицы результатов, он становится самым медленным методом из трех.
Заключительная мысль
Это интересно знать, но я предлагаю сделать то, что вы считаете наиболее читаемым / поддерживаемым,Только если вы действительно имеете дело со значительно большим набором данных, вам следует беспокоиться об этих микрооптимизациях.