[Israel.pm] for vs map

Yuval Kogman nothingmuch at woobling.org
Mon Jun 30 01:02:04 PDT 2008


I measured this

	sub abused_map {
		my @sqrt_results;
		map { push @sqrt_results, sqrt $_ } @results;
		return;
	}

and it turned out it's as fast as (well actually a hair faster than) the simple
for, which means that map is faster than for for iterating through elements,
but slower than for at building results.

I suspect that this is due to the aggregate nature: all the elements
are copied to the stack, and then all the elements are copied to the
array.

It's bullshit that the array size is preknown, etc.

As far as the opcodes go, map and for are pretty much the same, they
are looping constructs. Map is implemented kind of like 'while', the
mapping opcode is invoked repeatedly, once per element..

Reading through pp_mapwhile (in pp_ctl.c) it's appears that map actually needs
to copy parts of the stack often, due to the way that the input and the output
are both present on it.

There are comments int he source code, on how one could implement it better.
This also explains why abused_map is .

On Mon, Jun 30, 2008 at 09:10:46 +0300, Yossi Itzkovich wrote:
> Hi,
> 
> In "Perl Best Practices" by Damian Conway  I saw a guideline  called "Use map instead of for when generating new lists from old". He explains there very well ,why map() will run faster then simple for when you generate new list from old one, for example:  map is written in c, knows the final array size from the beginning (assuming you return a scalar from the mapping code) and more.
> 
> I tried  the code below on Solaris with (perl 5.6.1 and 5.8 ) and Linux (perl 5.10) and got results that map is slower 10-40% than simple for.
> Can someone explains it ?
> 
> The code:
> #! /bin/env perl
> 
> use strict;
> use warnings;
> use Benchmark qw(cmpthese);
> 
> my @results=( 1 .. 100000);
> 
> sub simpleFor
>   {
>     my @sqrt_results;
>     for my $result (@results)
>       {
>         push @sqrt_results, sqrt($result);
>       }
>   }
> 
> 
> sub optimizedFor
>   {
>      my @sqrt_results;
> 
>     # Preallocate as many elements as @results already has...
>     $#sqrt_results = $#results;
> 
>     for my $next_sqrt_result (0..$#results) {
> 
>         $sqrt_results[$next_sqrt_result] = sqrt $results[$next_sqrt_result];
>     }
>   }
> 
> sub usingMap
>   {
>     my @sqrt_results = map { sqrt $_ } @results;
>   }
> 
> 
> cmpthese (100,
>           {"simple for" => 'simpleFor();',
>            "optimized for" => 'optimizedFor()',
>            "with map" => 'usingMap()',
>           }
>          );
> 
> 
> 
> 
> _______________________________________________
> Perl mailing list
> Perl at perl.org.il
> http://perl.org.il/mailman/listinfo/perl

-- 
  Yuval Kogman <nothingmuch at woobling.org>
http://nothingmuch.woobling.org  0xEBD27418

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://perl.org.il/pipermail/perl/attachments/20080630/9b1b8463/attachment.pgp 


More information about the Perl mailing list