Обновить

Комментарии 10

Я думаю, что код не совсем верен. Замените в случае с array_ функциями $data на $newData, Вы увидите совершенно другие результаты.
image
время сливать карму
Очень жаль, что подобные вам выбрали хабр для слива собственной кармы.
Но некоторые выводы, уважаемые коллеги, сделать позволяют.

например что делать подобным образом подобные микро-бенчмарки не очень-то хорошая идея. Есть замечательный инструмент для подобного: phpbench. Как минимум с точки зрения статистической погрешности будет чище.


Далее, какие выводы еще мы можем сделать… Да собственно никаких. Методика проведения измерений мягко скажем не дает вообще никаких данных о том какие выводы мы можем сделать. Да, циклы будут всегда быстрее (особенно foreach) чем array_* функции тупо за счет отсутствия необходимости делать вызов функции на каждую итерацию. Причем что то что то — константа и на объемах выборок менее скажем десятков миллионов нам в целом плевать какой из вариантов мы используем.


Позвольте привести мою версию вашего бенчмарка (мне лень потому возьму только array_filter:


Результаты

Исходник


<?php

/**
 * @BeforeMethods({"init"})
 */
class ArrayFilterBenchmark
{
    public function init()
    {
        $this->data = range(1, 100000);
    }

    public function benchArrayFilter()
    {
        array_filter($this->data, function ($item) {
            return $item % 2;
        });
    }

    public function benchForeach()
    {
        $data = $this->data;
        $newData = array();
        foreach ($data as $item) {
            if ($item % 2) {
                 $newData[] = $item;
            }
        }
    }
}

Результаты


PhpBench 0.13.0. Running benchmarks.

\ArrayFilterBenchmark

    benchArrayFilter              I99 P0    [μ Mo]/r: 7,321.920 7,036.505 (μs)  [μSD μRSD]/r: 576.149μs 7.87%
    benchForeach                  I99 P0    [μ Mo]/r: 4,389.150 4,198.309 (μs)  [μSD μRSD]/r: 463.250μs 10.55%

2 subjects, 200 iterations, 2 revs, 0 rejects
(best [mean mode] worst) = 3,947.000 [5,855.535 5,617.407] 6,370.000 (μs)
⅀T: 1,171,107.000μs μSD/r 519.700μs μRSD/r: 9.212%

Запускалось на MacBook Pro 15" 2017, без XDebug.


PHP 7.1.4 (cli) (built: May  6 2017 10:02:00) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.1.4, Copyright (c) 1999-2017, by Zend Technologies

А вот другой аспект использования array_* функций, такой как возможность выстроить тело цикла как композицию функций, этот момент как раз таки и важен.

В наше время версии PHP 5 и 7 — это ниочём. Как минимум 4 версии надо рассматривать сегодня: 5.6, 7.0, 7.1 и 7.2.
И уж точно в результатах указать конкретные, хотя бы минорные.
Набор данных явно можно взять побольше.

проведите подобные тесты с помощью специализированного инструмента.
в ваших тестах, как минимум, ничего не сказано про потребляемую память и нет вариантов с разными данными в массивах.

Есть подозрение, что Вы измеряли время, которое тратится на 10000 вызовов функции и возврат результата из этой функции. Попробуйте применить более «тяжелые» вычисления и это время станет незаметно в общем результате.

Не понял, зачем у Вас
$data = array_walk(...)
, вы же затёрли массив $data на boolean-значение. Да и параметр $item, полагаю, следовало бы оформить как ссылку, чтобы соответствовать другим участкам кода.
Т.е. лучше оформить так этот кусок
array_walk($data, function (&$item) {
   $item += 1;
});
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации