Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options

Re^2: The High Price of Golf, and A Surprise

by Aristotle (Chancellor)
on Sep 07, 2002 at 11:25 UTC ( #195862=note: print w/replies, xml ) Need Help??

in reply to Re: The High Price of Golf, and A Surprise
in thread The High Price of Golf, and A Surprise

$ perl -MO=Deparse,x7 -e'sort { $a cmp $b } @x' sort @x; -e syntax OK $ perl -MO=Deparse,x7 -e'sort { $b cmp $a } @x' sort @x; -e syntax OK $ perl -MO=Deparse,x7 -e'sort { $a <=> $b } @x' sort @x; -e syntax OK $ perl -MO=Deparse,x7 -e'sort { $b <=> $a } @x' sort @x; -e syntax OK
So far it looks as though B::Deparse is broken.
$ perl -MO=Deparse,x7 -e'sort { $a->[0] cmp $b->[0] } @x' sort {$$a[0] cmp $$b[0];} @x; -e syntax OK
Obviously, it is not. Looks rather like Perl has builtins for all the common cases, then.

Makeshifts last the longest.

Replies are listed 'Best First'.
Re*Re^2: The High Price of Golf, and A Surprise
by bart (Canon) on Sep 07, 2002 at 11:45 UTC
    That's very interesting. I had noticed the same thing. Your conclusion might very well be correct, and I hadn't even thought of that possibility.

    Could the next be a special common case, too?

    perl -MO=Deparse,x7 -e'sort { $b cmp $a } @x' sort @x; -e syntax OK
    Well well well, it looks like it. It would explain why there appears to be no overhead for the callback. It can also explain the huge speed difference between "<=>" and "-": only the latter actually uses the callback. Otherwise, it would make no sense: "-" is a very fast operator, and checking the sign of the result should be just as fast. So it must be the overhead of the callback.

    Nevertheless, B::Deparse is broken, because the code it produces is obviously not equivalent to the original source code.

      That would be broken by necessity rather than in implementation. There simply is no way to represent a numerical sort without putting a callback in the source, but the compiled form of that sort doesn't use any callback. The choice is to represent either the original or the compiled form more closely. I prefer the current behaviour of emphasizing the compiled form since that's what the module is for, after all. Maybe that should be, if implementable, a user selectable option.

      Good catch about the reason of the - vs <=> slowdown. I didn't make that (so very obvious, in retrospect) connection.

      Makeshifts last the longest.

      Just for the record: firstly, it used to be that even simplistic sort subs such as { $a <=> $b } would call out to perl code, but that was changed to look for certain common cases and substitute a C implementation instead; I think that change first appeared in 5.6.1, judging by comparative timings here.

      Secondly, the bug in B::Deparse (which occurred simply because it wasn't immediately updated for the above change) was fixed in perl-5.8.0.

      Just to give a feel for the difference it makes spotting and substituting a C-based routine for a perl-based one, I added an extra variant of i_sship tweaked to avoid the optimization:

      i_sshipz => sub { @rin = sort { $a + 0 <=> $b } @nin },
      and here is the table I got (running under 5.8.0):
      Rate i_sshipz f_owtdi i_owtdi f_alpha i_alpha f_sship + i_sship i_sshipz 16.5/s -- -27% -28% -43% -52% -57% + -58% f_owtdi 22.6/s 37% -- -1% -22% -34% -41% + -42% i_owtdi 22.8/s 38% 1% -- -21% -33% -41% + -41% f_alpha 29.0/s 76% 28% 27% -- -15% -25% + -26% i_alpha 34.2/s 107% 51% 50% 18% -- -11% + -12% f_sship 38.5/s 134% 70% 69% 33% 13% -- + -1% i_sship 38.9/s 136% 72% 71% 34% 14% 1% + --

Re:x3 The High Price of Golf, and A Surprise
by grinder (Bishop) on Sep 07, 2002 at 21:15 UTC

    perldoc perldelta, for 5.6.1 says the following about sort:

    Simple sort() using { $a <=> $b } and the like are optimized

    Many common sort() operations using a simple inlined block are now optimized for faster performance.

    Mind you, I was under the impression that this optimisation occurred earlier, sometime back around the 5.004 to 5.005 timeframe. I'll have to go and look on some of my older machines.
    print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u'

Re: Re^2: The High Price of Golf, and A Surprise
by broquaint (Abbot) on Sep 07, 2002 at 17:04 UTC
    Small note which makes no difference to the deparsed syntax is that sort() used in a void context is a no-op (sp?). So all those sort()s could be deparsed down to
    $ perl -MO=Deparse,x7 -e'sort { $b <=> $a } @x' -e syntax OK


      The output would have been empty then; it is apparently not considered a NOP either:
      $ perl -MO=Deparse,x7 -e'1;' '???'; -e syntax OK
      ('???' is what B::Deparse produces when something gets optimized away.) I'm guessing that's because a sort may have side effects f.ex with tied arrays or inside the callback (if there is one), or something to that effect.

      Makeshifts last the longest.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://195862]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2017-03-28 21:53 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (342 votes). Check out past polls.