Well, most of the time foreach and map do different things, so I don't know about that. Maybe for (@in) { push @out, op($_); } is faster than @out = map { op($_) } @in;, but I think what you read might have been about the use of map as a substitute for for, as in ; map { $_ *= 2 } @list; instead of ; $_ *= 2 for @list;. You might read that it's bad practice because map builds a new list which is thrown away (people will tell you not to use map in void context). I think it is bad practice because map is supposed to turn a list into another, so the intent is clearer in the second case.
And to answer your question, since for can't be a sub expression (you shouldn't use the return value of a for loop), but the looping part is the inner part of the logic (the outer part being to choose between the cache and a new computation), to use the for loop, you need to extract the if/else logic out. $sum = $cache{$inner} //= sum map { $_->{value} } @{ $foo->{$inner} }{@keys}; becomes:
This version is also a little more correct, because it uses exists instead of defined (implicit with //) for the cache.unless (exists $cache{$inner}) { $cache{$inner} = 0; $cache{$inner} += $_->{value} for @{ $foo->{$inner} }{@keys}; # This might be a little faster, because perl doesn't have to build +the temporary list @{ $foo->{$inner} }{@keys} # $cache{$inner} += $foo->{$inner}{$_}{value} for @keys; } $sum = $cache{$inner};
In reply to Re^5: Optimize a perl block
by Eily
in thread Optimize a perl block
by IruP
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |