Sunday, April 8, 2012

Is there a performance penalty to using a BLOCK as the first argument to map when an EXPR would do?

In my previous post, I mentioned that there is a small performance penalty to using a block as the first argument to map.

A commenter posted a benchmark script which indicated that a block was much faster. It turns out, in his case, the block version was faster because it basically did no work. However, my benchmark script failed to find a real difference between the two.

This made me ask myself why I think there is a performance penalty to passing map a block. Well, I must have either heard it from someone I trust, or read it somewhere, or, least likely, measured it myself.

So, I wrote the following benchmark:

#!/usr/bin/env perl

use 5.014;
use Benchmark qw( cmpthese );

cmpthese -5, {
    EXPR => sub {
        my @x = map $_, 1 .. 100;
        return;
    },
    BLOCK => sub {
        my @x = map { $_ } 1 .. 100;
        return;
    },
};

which outputs:

         Rate BLOCK  EXPR
BLOCK 50621/s    --   -3%
EXPR  52194/s    3%    --

which seems to indicate a small advantage to passing an expression rather than a block when one can do that.

Now, to make things more interesting, I tried the following:

#!/usr/bin/env perl

use 5.014;
use Benchmark qw( cmpthese );

sub op { @_ };

cmpthese -5, {
    EXPR => sub {
        my @x = map op($_), 1 .. 100;
        return;
    },
    BLOCK => sub {
        my @x = map { op($_) } 1 .. 100;
        return;
    },
};

and got:

         Rate BLOCK  EXPR
BLOCK 22369/s    --  -13%
EXPR  25600/s   14%    --

So, it does look like using an expression as the first argument to map performs better than using a block.

No comments:

Post a Comment