in reply to sort routines crossing package lines

You can avoid exporting $a and $b by defining the sort routine like this:
sub caseless ($$) { lc $_[0] cmp lc $_[1] }
though the docs for sort say this is slower than using the un-prototyped version with $a and $b.

Replies are listed 'Best First'.
Re^2: sort routines crossing package lines
by ikegami (Patriarch) on Nov 24, 2004 at 22:32 UTC

    Update: I'm now saving the values for more realism, and corrected the extra 's' BrowserUK mentioned (which I had already fixed in the .pl file, just not in the post).

    Some concrete numbers:

    use Benchmark (); sub argless { $a cmp $b } sub proto($$) { $_[0] cmp $_[1] } sub args { $_[0] cmp $_[1] } my @array = qw( Perl may be copied only under the terms of either the Artistic Lice +nse or the GNU General Public License, which may be found in the Perl 5 source + kit. ); Benchmark::cmpthese(0, { inline => sub { my @sorted = sort { $a cmp $b } @array; }, argless => sub { my @sorted = sort argless @array; }, proto => sub { my @sorted = sort proto @array; }, args => sub { my @sorted = sort { args($a, $b) } @array; }, }); __END__ Rate args proto argless inline args 4634/s -- -57% -63% -81% proto 10735/s 132% -- -14% -57% argless 12462/s 169% 16% -- -50% inline 24920/s 438% 132% 100% --

    Here's a different comparison: (One that yeilds less unfair optimization)

    use Benchmark (); sub argless { $hash{$a } cmp $hash{$b } } sub proto($$) { $hash{$_[0]} cmp $hash{$_[1]} } sub args { $hash{$_[0]} cmp $hash{$_[1]} } our %hash = map { (''.rand()) => $_ } qw( Perl may be copied only under the terms of either the Artistic Lice +nse or the GNU General Public License, which may be found in the Perl 5 source + kit. ); Benchmark::cmpthese(0, { inline => sub { my @sorted = sort { $hash{$a} cmp $hash{$b} } k +eys %hash; }, argless => sub { my @sorted = sort argless k +eys %hash; }, proto => sub { my @sorted = sort proto k +eys %hash; }, args => sub { my @sorted = sort { args($a, $b) } k +eys %hash; }, }); __END__ Rate args proto argless inline args 2832/s -- -33% -42% -43% proto 4258/s 50% -- -13% -14% argless 4871/s 72% 14% -- -2% inline 4973/s 76% 17% 2% --

    Active Perl 5.6.1

      Not optimisations, errors.

      #! perl -slw use strict; #use sort use Benchmark (); sub argless { $a cmp $b } sub proto($$) { $_[0] cmp $_[1] } sub args { $_[0] cmp $_[1] } my @array = qw( Perl may be copied only under the terms of either the Artistic Lice +nse or the GNU General Public License, which may be found in the Perl 5 source + kit. ); Benchmark::cmpthese(-1, { inline => q[ sort { $a cmp $b } @array; ], argless => q[ sort argless @array; ], proto => q[ sort proto @array; ], args => q[ sort { args($a, $b) } @array; ], }); __END__ P:\test>410266 Possible attempt to separate words with commas at P:\test\410266.pl li +n Name "main::b" used only once: possible typo at P:\test\410266.pl line Name "main::a" used only once: possible typo at P:\test\410266.pl line Useless use of sort in void context at (eval 4) line 1. ... Useless use of sort in void context at (eval 182) line 1. Rate argless proto inline args argless 6619798/s -- -2% -8% -19% proto 6748958/s 2% -- -6% -18% inline 7189879/s 9% 7% -- -12% args 8216252/s 24% 22% 14% --

      Examine what is said, not who speaks.
      "But you should never overestimate the ingenuity of the sceptics to come up with a counter-argument." -Myles Allen
      "Think for yourself!" - Abigail        "Time is a poor substitute for thought"--theorbtwo         "Efficiency is intelligent laziness." -David Dunham
      "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
      I ran this on my machine -- a Dell Precision 340 running Fedora 2.6.something, Perl 5.8.4 --, fixing the arg(s)less problems and giving it a more hefty list to sort (~2500 items). My results from three runs:
      Rate proto argsless inline args proto 189740/s -- -0% -31% -32% argsless 190421/s 0% -- -30% -32% inline 273132/s 44% 43% -- -3% args 280139/s 48% 47% 3% -- Rate argsless proto inline args argsless 188543/s -- -0% -31% -33% proto 188746/s 0% -- -31% -33% inline 273988/s 45% 45% -- -3% args 281040/s 49% 49% 3% -- Rate proto argsless inline args proto 191010/s -- -1% -27% -30% argsless 192801/s 1% -- -27% -30% inline 262320/s 37% 36% -- -4% args 274019/s 43% 42% 4% --
      I'm not terribly surprised that inline is faster than the other named sub methods, but am quite surprsied that the 'args' version is the fastest.

      Update: Okay, adding an assignment in the benchmarked code gives more sensible results:

      Rate args proto argsless inline args 17.5/s -- -45% -49% -51% proto 31.8/s 82% -- -8% -11% argsless 34.6/s 98% 9% -- -3% inline 35.5/s 103% 12% 3% -- Rate args proto argsless inline args 17.3/s -- -46% -51% -52% proto 32.0/s 85% -- -9% -11% argsless 35.1/s 103% 10% -- -2% inline 35.7/s 107% 12% 2% -- Rate args proto inline argsless args 17.4/s -- -47% -49% -50% proto 33.0/s 90% -- -4% -5% inline 34.4/s 97% 4% -- -1% argsless 34.8/s 100% 5% 1% --
      --DrWhy

      "If God had meant for us to think for ourselves he would have given us brains. Oh, wait..."

      An interesting anomoly:

      sub argsless ...

      argless => sub { sort arg?less


      Examine what is said, not who speaks.
      "But you should never overestimate the ingenuity of the sceptics to come up with a counter-argument." -Myles Allen
      "Think for yourself!" - Abigail        "Time is a poor substitute for thought"--theorbtwo         "Efficiency is intelligent laziness." -David Dunham
      "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon