Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re: Is undef list assignment a no-op?

by BrowserUk (Pope)
on Mar 25, 2011 at 11:52 UTC ( #895454=note: print w/replies, xml ) Need Help??


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

I can't help but wonder why you would require the caller to pass a parameter you're never going to use?

If there is a good reason, (and I cannot think of one), then given the not insignificant difference in performance:

$a='a'x1e6; $b=12345; cmpthese -1,{ a=>q[ sub{ my( undef, $x ) = @_ }->( $a, $b ) ], b=>q[ sub{ my $x = $_[1] }->( $a, $b ) ], c=>q[ sub{ my( $unused, $x ); }->( $a, $b ) ], };; Rate a b c a 1703708/s -- -19% -20% b 2107186/s 24% -- -1% c 2129207/s 25% 1% --

I'd be asking myself if I thought that assignment to undef was any clearer than assignment to a variable called $unused?


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.

Replies are listed 'Best First'.
Re^2: Is undef list assignment a no-op?
by Anonymous Monk on Mar 25, 2011 at 11:56 UTC
    If there is a good reason, (and I cannot think of one), then given the not insignificant difference in performance:

    I don't know about good, but I think I've seen this scenario with callbacks, POE/LWP/Tk.... sometimes the first arg is large object, or large string, and you wish to avoid $_[0] or $_[CONSTANT] etc etc

      Good call++


      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.
Re^2: Is undef list assignment a no-op?
by ELISHEVA (Prior) on Mar 25, 2011 at 12:27 UTC

    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.

      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

      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% --

        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
Re^2: Is undef list assignment a no-op?
by repellent (Priest) on Mar 26, 2011 at 04:23 UTC
    Just as AnonyMonk mentioned. @job, I used the undef assignment as an optimization to avoid an intermediate copy of a large string, but still wanted to assign second arg onwards. foo is a function that wrote the string to a file, and is a code hotspot.

      Yes. I tend to avoid callback interfaces where possible; and pass large parameters, including huge scalars by reference rather than by value.

      But, I realise that we don't always have control over the modules we have to use, or the design choices of their authors.


      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.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://895454]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (4)
As of 2021-10-22 19:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My first memorable Perl project was:







    Results (85 votes). Check out past polls.

    Notices?