Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re: sorting objects #592

Closed
p5pRT opened this issue Sep 20, 1999 · 2 comments
Closed

Re: sorting objects #592

p5pRT opened this issue Sep 20, 1999 · 2 comments

Comments

@p5pRT
Copy link

p5pRT commented Sep 20, 1999

Migrated from rt.perl.org#1450 (status was 'resolved')

Searchable as RT1450$

@p5pRT
Copy link
Author

p5pRT commented Sep 20, 1999

From The RT System itself

In <199909140743.AAA10319@​activestate.com>, Gurusamy Sarathy writes​:
:What's wrong with​:
:
: sub mysort {
: my $c = caller;
: ${$c . '​::b'} <=> ${$c . '​::a'};
: }

Nothing​: I'm just so out of the habit of thinking in non-strict mode
that I didn't think of it (though the outer $ signs need to be doubled
to DTRT). As 'g_refs', performs better than my glob atrocities.

In <19990913234529.S14695@​hyperion.holzvania>, Benjamin Holzman writes​:
:Why not just put a class method in MyNum which knows how to sort MyNums?

Nothing wrong with that conceptually, but its not really what I'm trying
to achieve​: if you know that something is a sort comparison function, you
know all you need to know about it; if what you have instead is an 'object
sorting function', you need to start reading the documentation to work out
how to use it. So the sort comparison function requires less resources
for a human to use.

In <E11QwBP-0006ne-00@​ursa.cus.cam.ac.uk>, M.J.T. Guy writes​:
:If the other package is fixed and known at compile time, the simplest
:strategy is an appropriately placed "package"​:
:
: { package MyNum;
: print "Sorted​: ", join ' ', map $_->mystring, sort mysort @​list;
: };

You would have thought so; I was unable to get it working. You'll see it
commented out as 'h_pkg' below. I'm not sure whether the failure is my
own density or something on perl's part.

:If it's not fixed, you can do
:
: eval 'package MyNum; sort mysort @​list';

So how do you found out what package a subref was compiled in?

:> An alternative exists at the caller's end​:
:>
:> sort {
:> local($MyNum​::a, $MyNum​::b) = ($a, $b);
:> MyNum​::mysort
:> } @​list
:
:If you're paying the cost of a double subroutine call, you might as well
:make the compare subroutine a normal subroutine, and just write
:
: sort { MyNum​::mycompare($a, $b) } @​list;

True, and for the purposes of comparison I did include an 'e_subcall'
benchmark for that. In my original message, though, I was asking for
workarounds that affected either only the caller or only the comparison
routine.

Since f, g and (potentially) h are the only ones that satisfy my real
desire, I'll be using g for now.

Hugo
--- benchmark results ---
Benchmark​: timing 100000 iterations of a_simple, b_local, c_caller, e_subcall, f_globmg, g_refs...
  a_simple​: 15 wallclock secs ( 7.76 usr + 0.00 sys = 7.76 CPU)
  b_local​: 16 wallclock secs ( 8.70 usr + 0.00 sys = 8.70 CPU)
  c_caller​: 75 wallclock secs (37.72 usr + 0.00 sys = 37.72 CPU)
e_subcall​: 53 wallclock secs (25.79 usr + 0.00 sys = 25.79 CPU)
  f_globmg​: 112 wallclock secs (55.35 usr + 0.00 sys = 55.35 CPU)
  g_refs​: 84 wallclock secs (41.65 usr + 0.04 sys = 41.69 CPU)
--- benchmark code ---
#!/usr/bin/perl -w
use strict;
use Benchmark;
use vars qw/ @​x @​y /;
@​x = map MyNum->new($_), 0 .. 9;
sub localsort { $$b <=> $$a }

my %opts = (
  a_simple => q{
  @​y = sort { $$b <=> $$a } @​x
  },
  b_local => q{
  @​y = sort localsort @​x
  },
  c_caller => q{
  @​y = sort {
  local($MyNum​::a, $MyNum​::b) = ($a, $b);
  MyNum​::plain
  } @​x
  },
  e_subcall => q{
  @​y = sort { MyNum​::cmpcall($a, $b) } @​x
  },
  f_globmg => q{
  @​y = sort MyNum​::globmg @​x
  },
  g_refs => q{
  @​y = sort MyNum​::refs @​x
  },
# h_pkg => q{
# package MyNum;
# @​​::y = sort plain @​​::x
# },
);
if (@​ARGV) {
  timethese(shift, \%opts)
} else {
  foreach (sort keys %opts) {
  @​y = ();
  timeit(1, $opts{$_});
  my $str = join '.', map $$_, @​y;
  warn "$_ => $str\n" unless $str eq '9.8.7.6.5.4.3.2.1.0';
  }
}

package MyNum;
sub new {
  my($proto, $value) = @​_;
  bless \$value
}
sub plain {
  $$b <=> $$a
}
sub cmpcall {
  ${$_[1]} <=> ${$_[0]}
}
sub globmg {
  my $c = caller;
  no strict 'refs';
  $${*{"${c}​::b"}{SCALAR}} &lt;=&gt; $${*{"${c}​::a"}{SCALAR}}
}
sub refs {
  my $c = caller;
  no strict 'refs';
  $${$c . '​::b'} &lt;=&gt; $${$c . '​::a'}
}
--- end ---

@p5pRT
Copy link
Author

p5pRT commented Apr 22, 2003

@iabyn - Status changed from 'stalled' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant