Какая разница в производительности (если есть) между этими тремя подходами, которые используются для преобразования массива в другой массив?
- С помощью
foreach
- Использование
array_map
с лямбда / функцией закрытия - Использование
array_map
со «статической» функцией / методом - Есть ли другой подход?
Чтобы прояснить ситуацию, давайте посмотрим на примеры, которые все делают одинаково - умножая массив чисел на 10:
$numbers = range(0, 1000);
Для каждого
$result = array();
foreach ($numbers as $number) {
$result[] = $number * 10;
}
return $result;
Карта с лямбдой
return array_map(function($number) {
return $number * 10;
}, $numbers);
Карта со статической функцией, переданная как строковая ссылка
function tenTimes($number) {
return $number * 10;
}
return array_map('tenTimes', $numbers);
Есть ли другой подход? Я буду рад услышать на самом деле все различия между случаями сверху и любые входные данные, почему один должен использоваться вместо других.
Ответы:
FWIW, я просто сделал тест, так как плакат не сделал этого. Работает на PHP 5.3.10 + XDebug.
ОБНОВЛЕНИЕ 2015-01-22 сравните с ответом mcfedr ниже для дополнительных результатов без XDebug и более поздней версии PHP.
Я получаю довольно последовательные результаты с числами 1М за дюжину попыток:
Предположим, что нечеткая скорость карты при закрытии была вызвана тем, что замыкание, возможно, оценивается каждый раз, я также тестировал так:
Но результаты идентичны, подтверждая, что закрытие оценивается только один раз.
2014-02-02 ОБНОВЛЕНИЕ: дамп кодов
Вот дампы кода операции для трех обратных вызовов. Первый
useForeach()
:Тогда
useMapClosure()
и закрытие это вызывает:
тогда
useMapNamed()
функция:и названная функция вызывается,
_tenTimes()
:источник
useMapNamed
самом деле быстрее, чемuseArray
. Мысль, которую стоит упомянуть.lap
, вы не хотитеrange()
звонить выше первого микротайм-звонка? (Хотя, вероятно, незначительно по сравнению со временем для цикла.)Интересно запустить этот тест с отключенным xdebug, так как xdebug добавляет много накладных расходов, особенно на вызовы функций.
Это скрипт FGM, запускаемый с использованием 5.6 с xdebug
Без xdebug
Здесь есть только очень небольшая разница между версиями foreach и closure.
Также интересно добавить версию с закрытием
use
Для сравнения добавлю:
Здесь мы можем видеть, что это влияет на версию закрытия, тогда как массив заметно не изменился.
19/11/2015 Я также добавил результаты, используя PHP 7 и HHVM для сравнения. Выводы похожи, хотя все гораздо быстрее.
источник
array_map
(и связанная с ним функцияarray_reduce
,array_filter
) позволяет писать красивый код. Еслиarray_map
было бы намного медленнее, это было бы причиной для использованияforeach
, но это очень похоже, поэтому я буду использоватьarray_map
везде, где это имеет смысл.Это интересно. Но я получил противоположный результат со следующими кодами, которые упрощены из моих текущих проектов:
Вот мои данные тестирования и коды:
Результат:
Мои тесты были в производственной среде LAMP без xdebug. Я бродил xdebug, чтобы замедлить производительность array_map.
источник
array_map
;)array_map
иforeach
использование Xhprof. И это интересноarray_map
потребляет больше памяти, чем `foreach`.