array_* vs foreach или PHP7 vs PHP5

в 17:53, , рубрики: php, php 5 php 7

Добрых суток. Как-то за кадром остался вопрос прироста производительности стандартных функций PHP при работе с массивами в версии 7.*.

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

А вот здесь можно уже увидеть тесты, для 7-ой версии. И то не все так в ней однозначно. В тестах от 19/11/2015 циклы и встроенные функции сравнялись по производительности, и только последний топик наводит нас на размышления.

А что же по итогу… Я решил все проверить самостоятельно и прогнать несколько тестов…

1) array_filter

исходный код

$data = range(0, 10000);
$start = microtime(true);
$data = array_filter($data, function ($item) {
    return $item%2;
});
$end = microtime(true);
 
echo $end - $start.'  ';

 $data = range(0, 10000);
$start = microtime(true);
$newData = array();
foreach ($data as $item) {
    if ($item%2) {
        $newData[] = $item;
    }
}
$end = microtime(true);
 
echo $end - $start.'  ';

 $data = range(0, 10000);
$start = microtime(true);
$newData = array();
$numItems = count($data);
for($i=1;$i<=$numItems-1;$i++) {
    if ($data[$i]%2) {
        $newData[] = $data[$i];
    }
}
$end = microtime(true);
 
echo $end - $start.'  ';


 $data = range(0, 10000);
$start = microtime(true);
$newData = array();
$numItems = count($data);
$i = 0;
while ($i <= $numItems-1) {
    if ($data[$i]%2) {
        $newData[] = $data[$i];
    }
    $i++;
}
$end = microtime(true);
 
echo $end - $start.'  ';

Округленно…

функция PHP5 PHP7
array_filter 0.00282 0.00136
foreach 0.0013 0.00045
for 0.00171 0.00072
while 0.00145 0.00054

2) array_map

исходный код


<?php
$data = range(0, 10000);

$start = microtime(true);
$data = array_map(function ($item) {
    return $item+1;
}, $data);
$end = microtime(true);
 
echo $end - $start;
 
$data = range(0, 10000);
$start = microtime(true);
$newData = array();
foreach ($data as $item) {
    $newData[] = $item+1;
}
$end = microtime(true);
 
echo $end - $start;
 
$data = range(0, 10000);
$start = microtime(true);
$newData = array();
$numItems = count($data);
for($i=0;$i<$numItems;$i++) {
    $newData[] = $data[$i]+1;
}
$end = microtime(true);
 
echo $end - $start;
 
$data = range(0, 10000);
$start = microtime(true);
$newData = array();
$numItems = count($data);
$i = 0;
while ($i < $numItems) {
    $newData[] = $data[$i];
    $i++;
}
$end = microtime(true);
 
echo $end - $start;

функция PHP5 PHP7
array_map 0.00462 0.00094
foreach 0.00155 0.00033
for 0.00220 0.00044
while 0.00169 0.00054

3) array_walk

исходный код


$data = range(0, 10000);

$start = microtime(true);
$data = array_walk($data, function ($item) {
    return $item+1;
});
$end = microtime(true);
 
echo $end - $start;
 $data = range(0, 10000);
$start = microtime(true);
$newData = array();
foreach ($data as $item) {
    $newData[] = $item+1;
}
$end = microtime(true);
 
echo $end - $start;
 $data = range(0, 10000);
$start = microtime(true);
$newData = array();
$numItems = count($data);
for($i=0;$i<$numItems;$i++) {
    $newData[] = $data[$i]+1;
}
$end = microtime(true);
 
echo $end - $start;
 $data = range(0, 10000);
$start = microtime(true);
$newData = array();
$numItems = count($data);
$i = 0;
while ($i < $numItems) {
    $newData[] = $data[$i];
    $i++;
}
$end = microtime(true);
 
echo $end - $start;

функция PHP5 PHP7
array_walk 0.00285 0.00101
foreach 0.00290 0.00088
for 0.00219 0.00043
while 0.00173 0.00086

4) array_reduce

исходный код


$data = range(0, 10000);

$start = microtime(true);
$data = array_reduce($data, function ($carry, $item) {
    $carry += $item;
    return $carry;
},0);
$end = microtime(true);
echo $end - $start;

 $data = range(0, 10000);
$start = microtime(true);
$newData = 0;
foreach ($data as $item) {
    $newData+= $item;
}
$end = microtime(true);

echo $end - $start;
 $data = range(0, 10000);
$start = microtime(true);
$newData = 0;
$numItems = count($data);
for($i=0;$i<$numItems;$i++) {
    $newData+= $data[$i];
}
$end = microtime(true);


echo $end - $start;
 $data = range(0, 10000);
$start = microtime(true);
$newData = 0;
$numItems = count($data);
$i = 0;
while ($i < $numItems) {
    $newData+= $data[$i];
    $i++;
}
$end = microtime(true);
echo $end - $start;

функция PHP5 PHP7
array_reduce 0.00239 0.00092
foreach 0.00044 0.00020
for 0.00066 0.00029
while 0.00062 0.00029

Понятно, что цифры относительны. Но некоторые выводы, уважаемые коллеги, сделать позволяют.

Автор: jkd

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js