develooper Front page | perl.perl5.porters | Postings from November 2022

Why is map BLOCK LIST slower than map EXPR, LIST

Thread Next
From:
Paul "LeoNerd" Evans
Date:
November 28, 2022 10:29
Subject:
Why is map BLOCK LIST slower than map EXPR, LIST
Message ID:
20221128102937.46d316db@shy.leonerd.org.uk
While recently discussing Graham Knop's recent RFC idea about map and
grep, someone said to me they tend to prefer `map EXPR, LIST` on short
code, because it runs faster. I seemed somewhat dubious about this -
surely it should compile to the same thing in those cases? But yet, it
appears not.

According to these benchmark numbers[1] on a simple map to find the
lengths of some strings:

$ eachperl -I. -MBetterBenchmark=cmpthese \
  -e'my @x = 1..5000000;
     cmpthese -3, {
        block => sub { map { length } @x },
        expr  => sub { map length, @x }
     }'

I get:

  --- perl5.14.4 --- 
expr : 4.754sec
block: 5.019sec (5% slower)

  --- perl5.16.3 --- 
expr : 4.476sec
block: 5.421sec (21% slower)

  --- perl5.18.4 --- 
expr : 3.966sec
block: 4.627sec (16% slower)

  --- perl5.20.3 --- 
expr : 4.554sec
block: 5.400sec (18% slower)

  --- perl5.22.4 --- 
expr : 4.040sec
block: 4.615sec (14% slower)

  --- perl5.24.4 --- 
expr : 4.000sec
block: 4.710sec (17% slower)

  --- perl5.26.3 --- 
expr : 3.789sec
block: 4.394sec (15% slower)

  --- perl5.28.3 --- 
expr : 3.887sec
block: 4.722sec (21% slower)

  --- perl5.30.3 --- 
expr : 3.453sec
block: 4.305sec (24% slower)

  --- perl5.32.1 --- 
expr : 3.829sec
block: 4.461sec (16% slower)

  --- perl5.34.1 --- 
expr : 3.426sec
block: 3.986sec (16% slower)

  --- perl5.36.0 --- 
expr : 4.498sec
block: 5.055sec (12% slower)


Numbers vary depending on build, but consistently the map BLOCK form
does appear to be at least 15% or more slower than the equivalent
map EXPR.

I don't know why it ought to be in this case. Semantically the two subs
do exactly the same work, so they should take exactly the same time to
execute.

Perhaps this might make for a good code-dive project for someone, to
try to look into why and fix it? It'd be great if we could always use
the BLOCK form without having to worry that the code is slower than if
we had used EXPR.


[1]: I find that core's "Benchmark.pm" is a great way to generate
     random timing noise based on whatever else is happening on your
     server, so I wrote BetterBenchmark that is much more immune to such
     noise because it interleaves many much smaller runs of the code
     under test; such timing noise gets spread among all the candidates
     roughly equally. Find it attached. I may turn it into a real CPAN
     (or core) module someday.

-- 
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk      |  https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/  |  https://www.tindie.com/stores/leonerd/

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About