Performance of foreach, array_map with lambda and array_map with static function

Pavel S. picture Pavel S. · Aug 9, 2013 · Viewed 77.1k times · Source

What's the performance difference (if there is any) between these three approaches, both used to transform an array to another array?

  1. Using foreach
  2. Using array_map with lambda/closure function
  3. Using array_map with 'static' function/method
  4. Is there any other approach?

To make myself clear, let's have look at the examples, all doing the same - multiplying the array of numbers by 10:

$numbers = range(0, 1000);

Foreach

$result = array();
foreach ($numbers as $number) {
    $result[] = $number * 10;
}
return $result;

Map with lambda

return array_map(function($number) {
    return $number * 10;
}, $numbers);

Map with 'static' function, passed as string reference

function tenTimes($number) {
    return $number * 10;
}
return array_map('tenTimes', $numbers);

Is there any other approach? I will be happy to hear actually all differences between the cases from above, and any inputs why one should be used instead of others.

Answer

mcfedr picture mcfedr · Oct 23, 2014

Its interesting to run this benchmark with xdebug disabled, as xdebug adds quite a lot of overhead, esp to function calls.

This is FGM's script run using 5.6 With xdebug

ForEach   : 0.79232501983643
MapClosure: 4.1082420349121
MapNamed  : 1.7884571552277

Without xdebug

ForEach   : 0.69830799102783
MapClosure: 0.78584599494934
MapNamed  : 0.85125398635864

Here there is only a very small difference between the foreach and closure version.

Its also interesting to add a version with a closure with a use

function useMapClosureI($numbers) {
  $i = 10;
  return array_map(function($number) use ($i) {
      return $number * $i++;
  }, $numbers);
}

For comparison I add:

function useForEachI($numbers)  {
  $result = array();
  $i = 10;
  foreach ($numbers as $number) {
    $result[] = $number * $i++;
  }
  return $result;
}

Here we can see it makes an impact on the closure version, whereas the array hasn't noticeably changed.

19/11/2015 I have also now added results using PHP 7 and HHVM for comparison. The conclusions are similar, though everything is much faster.

PHP 5.6

ForEach    : 0.57499806880951
MapClosure : 0.59327731132507
MapNamed   : 0.69694859981537
MapClosureI: 0.73265469074249
ForEachI   : 0.60068697929382

PHP 7

ForEach    : 0.11297199726105
MapClosure : 0.16404168605804
MapNamed   : 0.11067249774933
MapClosureI: 0.19481580257416
ForEachI   : 0.10989861488342

HHVM

ForEach    : 0.090071058273315
MapClosure : 0.10432276725769
MapNamed   : 0.1091267824173
MapClosureI: 0.11197068691254
ForEachI   : 0.092114186286926