array_walk vs array_map vs foreach
Asked Answered
R

3

33

I'm trying to compare these three but it seems only array_map works.

$input = array( '  hello   ','whsdf                                    ','                              lve you','                              ');
$input2 = array( '  hello   ','whsdf                                    ','                              lve you','                              ');
$input3 = array( '  hello   ','whsdf                                    ','                              lve you','                              ');

$time_start = microtime(true);
$input = array_map('trim',$input);
$time_end = microtime(true);
$time = $time_end - $time_start;

echo "Did array_map in $time seconds<br>";

foreach($input as $in){
    echo "'$in': ".strlen($in)."<br>";
}

////////////////////////////////////////////////

$time_start = microtime(true);
array_walk($input2,'trim');
$time_end = microtime(true);
$time = $time_end - $time_start;

echo "Did array_walk in $time seconds<br>";

foreach($input2 as $in){
    echo "'$in': ".strlen($in)."<br>";
}

////////////////////////////////////////////////


$time_start = microtime(true);
foreach($input3 as $in){
    $in = trim($in);
}
$time_end = microtime(true);
$time = $time_end - $time_start;

echo "Did foreach in $time seconds<br>";

foreach($input3 as $in){
    echo "'$in': ".strlen($in)."<br>";
}

What Am I Doing Wrong? Here's the output:

Did array_map in 0.00018000602722168 seconds
'hello': 5
'whsdf': 5
'lve you': 7
'': 0
Did array_walk in 0.00014209747314453 seconds
' hello ': 10
'whsdf ': 41
' lve you': 37
' ': 30
Did foreach in 0.00012993812561035 seconds
' hello ': 10
'whsdf ': 41
' lve you': 37
' ': 30

It's not trimming for array_walk and the foreach loop.

Radiometeorograph answered 5/5, 2012 at 3:45 Comment(1)
If you want to know the performance, see the graphs from the article.Papery
D
21

array_walk doesn't look at what result function gives. Instead it passes callback a reference to item value. So your code for it to work needs to be

function walk_trim(&$value) {
    $value = trim($value);
}

foreach doesn't store changed values itself either. Change it to

foreach ($input3 as &$in) {
    $in = trim($in);
}

Read more about references.

Deryl answered 5/5, 2012 at 3:54 Comment(2)
for the foreach: why do i have to pass it by reference? it's not a function right?Sleigh
It isn't, right. But when you declare it without a reference that's what you get - a value, not item itself. It would only work without reference if items were objects. BTW, I'd suggest you do multiple cycles for the methods you're testing and print average on X runs. Your actions don't really take much time and microseconds they take are very approximate.Deryl
V
5

As of PHP 5.3 Anonymous Functions possible. ex:

$arr = array('1<br/>','<a href="#">2</a>','<p>3</p>','<span>4</span>','<div>5</div>');
array_walk($arr, function(&$arg){
    $arg = strip_tags($arg);
});
var_dump($arr); // 1,2,3,4,5 ;-)

Have fun.

Vorlage answered 5/6, 2013 at 13:39 Comment(7)
That is one ugly-looking array.Pre
Anyhow it looks much better than ugly loops. Today's trend is using less loops, ifs, switches and is encountered as best practices.Vorlage
@ValentinRusk I didn't hear anything about the so called "trend". Can you elaborate?Morley
@ValentinRusk The design patterns/principles have nothing to do with using array_walk against foreach. None of those is even using objects. How is this related to OOP then? :)Morley
OOP doesn't discourage use of loops... SOLID has nothing to do with loops. In fact, array_map is a functional programming paradigm en.wikipedia.org/wiki/Map_%28higher-order_function%29Dalury
for the record, this "ugly" code is functional code.Sighted
@PetrPeller after almost 5 years passed and you guys all worked with php, js, ruby, pythons, etc. hope you all realised that the trend that you never heard of now persistently inbound into every modern framework ;-)Vorlage
S
2

For the record, I did the change proposed by slava but for fairness, I used the same function for every method and not only to array_walk:

function walk_trim(&$value) {
    $value = trim($value);
    return $value; // needed by array_map
}
  • Did array_map in 0.0098860263824463 seconds
  • Did array_walk in 0.00996994972229 seconds
  • Did foreach in 0.0095021724700928 seconds

And foreach is slightly fast (PHP 8.2x64 windows)

Sighted answered 27/3, 2023 at 1:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.