in reply to Re^2: Map Vs Foreach
in thread Map Vs Foreach

For what its worth:
I was unhappy about your benchmark, since the two types of code did not appear to be the same:
@arr1 = map { push @arr1, ($_+ 2) } @data;
in particular seemed suspect to me. Also the order of memory allocation can affect benchmarks. When I ran the supplied code the foreach loop worked fine (5 seconds on my machine) but the map gave Out of memory!.

So I rewrote each part to be a subroutine, and tided the map so it looked like this:
sub mapsub { my @arr; @arr = map { ($_ + 2) } @data; }
I can't say if that was faster, because it still gives Out of memory! Must be something to do with a temporary list (5.10.1 on Windows). Reducing the size of @data by a factor of 10 gives map taking around twice as long, and each taking under a second.

Replies are listed 'Best First'.
Re^4: Map Vs Foreach
by Ratazong (Monsignor) on Nov 26, 2009 at 10:24 UTC
    Some more benchmarking:
    my @data = (1..8000000); foreach my $x (@data) { push @arr, ($x+2); } @arr1 = map { $_+ 2 } @data; @arr2 = map { push @arr2, ($_+ 2) } @data;
    resulted in the following measurement-output:

    Time taken by foreach loop was 2 wallclock secs ( 2.27 usr 0.03 sys + 0.00 cusr 0.00 csys = 2.30 CPU) seconds
    Time taken by map block was 4 wallclock secs ( 3.39 usr 0.34 sys + 0.00 cusr 0.00 csys = 3.73 CPU) seconds
    Time taken by map block (with push) was 5 wallclock secs ( 4.63 usr 0.05 sys + 0.00 cusr 0.00 csys = 4.67 CPU) seconds


    best regards, Rata
    (a bit surprised about the performance-differences)(btw.: ActiveState perl 5.8.8)

    Update
    As Ikegami pointed out correctly (thanks!!), the line with @arr2 is wrong. Changing it to

    map { push @arr2, ($_+ 2) } @data;

    results in

    Time taken by map block (with push) was 3 wallclock secs ( 2.33 usr 0.00 sys + 0.00 cusr 0.00 csys = 2.33 CPU) seconds

    being similar fast as the foreach ...

      that last line is buggy.
      @arr2 = map { push @arr2, ($_+ 2) } @data;
      should be
      map { push @arr2, ($_+ 2) } @data;