in reply to Memory leak in map function?
My hunch is that, even though map is in void context, it is still generating the return-list that is scalar(@objects) elements large. In your case, every element of this anonymous list is undef due to the last line of the block. To test this hunch, change the code to the following:
.. so that the return-list never gets added onto. See if that brings performance in line with the foreach (not that I'm encouraging you to stay with the void-context map here).. <runs off to benchmark...>map { $module->target($_); my $results = $module->process(); (); } @objects;
I am also under the impression that the second method should be faster. Is that true?
I highly doubt that, but don't know enough about the internals to say one way or another. Clearly (from your experience) in void context, map seems to have the extra overhead of maintaining the return-list.
PS: undef $results is not needed, as $results falls out of scope at the end of the block each time. But you probably just had that in to double-check your suspicion of a memory leak..
Update: Yep, the benchmark showed that there is a significant improvement by having (); as the last statement of the void-context map BLOCK:
.. My simple for loop was faster than both, but please avoid map in void context for semantic reasons alone.use Benchmark 'cmpthese'; + my @objects = (1 .. 100_000); + cmpthese( -1, { map1 => sub { map { my $xyz = $_ + 1000; undef $xyz; } @objects; 1; +}, map2 => sub { map { my $xyz = $_ + 1000; (); } @objects; 1; +}, for => sub { for (@objects) { my $xyz = $_ + 1000; undef $xyz } 1; +} }); __END__ Benchmark: running for, map1, map2 for at least 1 CPU seconds... for: 1 wallclock secs ( 1.10 usr + 0.01 sys = 1.11 CPU) @ 11 +.71/s (n=13) map1: 1 wallclock secs ( 1.08 usr + 0.00 sys = 1.08 CPU) @ 7 +.41/s (n=8) map2: 2 wallclock secs ( 1.06 usr + 0.00 sys = 1.06 CPU) @ 10 +.38/s (n=11) Rate map1 map2 for map1 7.41/s -- -29% -37% map2 10.4/s 40% -- -11% for 11.7/s 58% 13% --
blokhead
|
|---|