As has been mentioned in previous questions of this sort,
for is faster and requires less memory than
map, because
map creates a temporary in-memory list to return, which is then transformed into a hash. This effect is much more pronounced for large arrays than small ones... in fact, let's run some benchmarks:
use strict;
use warnings;
use Benchmark qw(cmpthese);
for my $size (5,50,500) {
my @lol = map { [$_, qw(some random useless data)] } (1..$size);
print "\n\nComparing 'map' and 'for' hash-assignment from array of $
+size elements\n";
cmpthese (-2, {
for => sub { my %hash; $hash{$_->[0]} = $_ for @lol; },
map => sub { my %hash; %hash = map{$_->[0] => $_} @lol; }
});
}
## OUTPUTS ##
Comparing 'map' and 'for' hash-assignment from array of 5 elements
Benchmark: running for, map, each for at least 2 CPU seconds...
for: 3 wallclock secs ( 2.22 usr + 0.00 sys = 2.22 CPU) @ 77
+311.15/s (n=171940)
map: 1 wallclock secs ( 2.19 usr + 0.00 sys = 2.19 CPU) @ 55
+606.20/s (n=122000)
Rate map for
map 55606/s -- -28%
for 77311/s 39% --
Comparing 'map' and 'for' hash-assignment from array of 50 elements
Benchmark: running for, map, each for at least 2 CPU seconds...
for: 2 wallclock secs ( 2.04 usr + 0.00 sys = 2.04 CPU) @ 99
+92.17/s (n=20414)
map: 2 wallclock secs ( 2.12 usr + 0.00 sys = 2.12 CPU) @ 56
+57.09/s (n=12010)
Rate map for
map 5657/s -- -43%
for 9992/s 77% --
Comparing 'map' and 'for' hash-assignment from array of 500 elements
Benchmark: running for, map, each for at least 2 CPU seconds...
for: 3 wallclock secs ( 2.01 usr + 0.00 sys = 2.01 CPU) @ 94
+8.83/s (n=1910)
map: 2 wallclock secs ( 2.07 usr + 0.00 sys = 2.07 CPU) @ 33
+5.75/s (n=696)
Rate map for
map 336/s -- -65%
for 949/s 183% --
For large arrays of 500 elements, using the seemingly innocuous
map technique is nearly
three times slower. For your typical 50-element array,
map is almost twice as slow.
I'm actually surprised the performance penalty was so pronounced.