http://qs321.pair.com?node_id=895465


in reply to Re: Is undef list assignment a no-op?
in thread Is undef list assignment a no-op?

Small oversight - your benchmark with $unused never makes an assignment from @_. When I fixed the typo and reran it, (undef, $x)= @_ was marginally faster than ($unused, $x) = @_ though not by an amount I consider significant (3%). -- Tested on Perl 5.10.0, system Perl for Debian Lenny, 32bit.

use Benchmark qw(cmpthese); my $a1='a'x1e6; my $b1=12345; cmpthese -1,{ a=>q[ sub{ my( undef, $x) = @_ }->( $a1, $b1 ) ], b=>q[ sub{ my $x = $_[1] }->( $a1, $b1 ) ], c=>q[ sub{ my( $unused, $x ) = @_;}->( $a1, $b1 ) ], }; # Output Rate c a b c 649176/s -- -3% -33% a 670690/s 3% -- -30% b 963764/s 48% 44% --

Update added Perl version and platform; clarified ranking of results.

Replies are listed 'Best First'.
Re^3: Is undef list assignment a no-op?
by Tux (Canon) on Mar 25, 2011 at 12:58 UTC

    That performance difference seems to be consistent accross all perl versions. I ran the following through 79 perl versions

    use strict; use Benchmark qw(cmpthese); my $a1 = "a" x 1e6; my $b1 = 12345; cmpthese 2000000, { "und" => q[ sub{ my (undef, $x) = @_ }->($a1, $b1) ], "skp" => q[ sub{ my $x = $_[1] }->($a1, $b1) ], "var" => q[ sub{ my ($unused, $x) = @_;}->($a1, $b1) ], };

    I note that 5.13.8 unthreaded is a weird reproducible result:

    Rate var und skp var 1694915/s -- -27% -41% und 2325581/s 37% -- -19% skp 2857143/s 69% 23% --

    Enjoy, Have FUN! H.Merijn
Re^3: Is undef list assignment a no-op?
by BrowserUk (Patriarch) on Mar 25, 2011 at 14:56 UTC

    Acknowledged++ My benchmark was badly borken.

    Unfortunately, so is yours. You need to use our variables for the parameters, otherwise they are not being seen by the compiled code.

    Correct that, and you are in for a big surprise :)


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      On my machine (Debian Lenny, Perl 5.10.0 as above) the sequencing and clustering of results is still the same even if our variables are used. In truth the only thing that is changing is the specific values being passed in. There is no fundamental difference in the two benchmarks.

      As regards benchmark results, with our variables, the only difference is that the gap between und/var on one hand and $x=$_[1] on the other widens considerably. That is hardly surprising though. ($unused, $x) is copying a 1 million character array into $unused. $x=$_[1] is not.

      The result does vividly illustrate that undef in a list is not a no-op. If (undef, $x) = @_ were a no-op its performance should cluster with $x=$_[1], but it doesn't. It acts like ($unused, $x) which copies a very big string. However, that clustering pattern is also identical to the results tux and I got, albeit less dramatically. With either benchmark, if you want to use lists on the left side of an assignment from an array, then you are still no better off using $unused instead of undef.

      Are you seeing something different on your machine?

      use Benchmark qw(cmpthese); our $a1='a'x1e6; our $b1=12345; cmpthese -1,{ und=>q[ sub{ my( undef, $x) = @_ }->( $a1, $b1 ) ], skp=>q[ sub{ my $x = $_[1] }->( $a1, $b1 ) ], var=>q[ sub{ my( $unused, $x ) = @_;}->( $a1, $b1 ) ], }; #output Rate var und skp var 66.3/s -- -10% -100% und 73.5/s 11% -- -100% skp 945230/s 1424595% 1286780% --

        Now my results look much like Tux's:

        C:\test>junk74 Rate c a b c 2566/s -- -100% -100% a 1761856/s 68575% -- -18% b 2158325/s 84029% 23% --

        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
        Thanks for the benchmark! (Same thanks goes to Tux and BrowserUk).

        Hmm. This is what I got. I changed to using subs instead:
        use Benchmark qw(cmpthese); my $a1='a'x9999999; my $b1=12345; cmpthese -1,{ und=> sub { sub{ my( undef, $x) = @_ }->( $a1, $b1 ) }, skp=> sub { sub{ my $x = $_[1] }->( $a1, $b1 ) }, var=> sub { sub{ my( $unused, $x ) = @_;}->( $a1, $b1 ) }, }; __END__ Rate var und skp var 50.2/s -- -100% -100% und 516222/s 1027915% -- -32% skp 762291/s 1517942% 48% --

      But now you're not playing fair :)

      The diff is very much depending on what the first arg is, and how common is a first argument of a string of 1 Mb?

      $a1 = "a" x 1e6"; Rate var und skp var 11049/s -- -100% -100% und 2812991/s 25360% -- -20% skp 3495253/s 31535% 24% -- $a1 = "a" x 1e4; Rate var und skp var 701455/s -- -75% -80% und 2840570/s 305% -- -17% skp 3440640/s 391% 21% -- $a1 = "a" x 100; Rate var und skp var 2055647/s -- -28% -43% und 2858267/s 39% -- -21% skp 3633679/s 77% 27% -- $a1 = "a"; Rate var und skp var 2075800/s -- -25% -41% und 2780315/s 34% -- -21% skp 3528861/s 70% 27% -- $a1 = 1; Rate var und skp var 2293760/s -- -14% -31% und 2672341/s 17% -- -20% skp 3340426/s 46% 25% -- $a1 = undef; Rate var und skp var 2429401/s -- -14% -30% und 2840570/s 17% -- -18% skp 3479788/s 43% 23% -- $a1 = sub { 1; }; Rate var und skp var 2383127/s -- -16% -32% und 2824827/s 19% -- -19% skp 3508785/s 47% 24% -- $a1 = bless { a1 => 1 }; Rate var und skp var 2383127/s -- -18% -31% und 2912710/s 22% -- -15% skp 3429921/s 44% 18% --

      Enjoy, Have FUN! H.Merijn
        But now you're not playing fair :)

        I was only doing what the op did. Except he used my $big = 'a' x 99999999;


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.