Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   Question re Conway's "Perl Best Practices" - Sort::Maker (http://www.velocityreviews.com/forums/t897797-question-re-conways-perl-best-practices-sort-maker.html)

usenet@DavidFilmer.com 05-04-2006 01:30 AM

Question re Conway's "Perl Best Practices" - Sort::Maker
 
Uri reminded me (in another thread: http://tinyurl.com/nyclh) of his
module, Sort::Maker, which Damian Conway praised in "Perl Best
Practices" (page 164-165), and which I have been meaning to learn more
about.

However, I am having difficulty with Damian's example.

Kindly consider this small sample program wrapped around some PBP
example code which I have retyped verbatum (adding only my own
statement to populate sample @names):

#!/usr/bin/perl
use strict; use warnings;
use Sort::Maker;

my @names = qw{ Fred Barney Wilma Betty };

make_sorter(name => 'sort_len', code => sub{ length }, ST => 1);
# and later...
my @names_shortest_first = sort_len(@names);

__END__

The script fails with:
Undefined subroutine &main::sort_len...

But, according to the Sort::Maker perldocs, 'name' is
>>> a value option which exports the generated sort sub to that name.


So I believe that sort_len should be exported when the make_sorter
statement is executed. But it doesn't seem to be working.

What am I doing wrong?

(perl, v5.8.4 built for aix, $Sort::Maker::VERSION == 0.05)


--
http://DavidFilmer.com


DJ Stunks 05-04-2006 03:01 AM

Re: Question re Conway's "Perl Best Practices" - Sort::Maker
 
usenet@DavidFilmer.com wrote:
> Uri reminded me (in another thread: http://tinyurl.com/nyclh) of his
> module, Sort::Maker, which Damian Conway praised in "Perl Best
> Practices" (page 164-165), and which I have been meaning to learn more
> about.
>
> However, I am having difficulty with Damian's example.
>
> Kindly consider this small sample program wrapped around some PBP
> example code which I have retyped verbatum (adding only my own
> statement to populate sample @names):
>
> #!/usr/bin/perl
> use strict; use warnings;
> use Sort::Maker;
>
> my @names = qw{ Fred Barney Wilma Betty };
>
> make_sorter(name => 'sort_len', code => sub{ length }, ST => 1);
> # and later...
> my @names_shortest_first = sort_len(@names);
>
> __END__
>
> The script fails with:
> Undefined subroutine &main::sort_len...
>
> But, according to the Sort::Maker perldocs, 'name' is
> >>> a value option which exports the generated sort sub to that name.

>
> So I believe that sort_len should be exported when the make_sorter
> statement is executed. But it doesn't seem to be working.
>
> What am I doing wrong?
>
> (perl, v5.8.4 built for aix, $Sort::Maker::VERSION == 0.05)


Well, the first thing I did was grab my copy of _PBP_ and check that
you weren't nuts. Which you aren't :)

The second thing I did was run your sample code, with the same results.

I then added an error check on the make_sorter call and it died with
the error:
Unable to create sorter: make_sorter: Unknown option or key 'code'

So then I had a look at the docs (which I hadn't ever looked at before)
and managed to munge up the following, which works.

I'm sure Pastor Conway ran all the code in his book, so maybe something
changed. Only Uri knows for sure.

-jp

#!/usr/bin/perl
use strict; use warnings;

use Sort::Maker;

my @names = qw{ Fred Barney Wilma Betty };

make_sorter(
qw( ST ),
name => 'sort_len',
string => {
code => sub { length }
}
) or die "Unable to create sorter: $@";

print join "\n", sort_len(@names);

__END__


Uri Guttman 05-04-2006 04:12 AM

Re: Question re Conway's "Perl Best Practices" - Sort::Maker
 
>>>>> "DS" == DJ Stunks <DJStunks@gmail.com> writes:

DS> So then I had a look at the docs (which I hadn't ever looked at before)
DS> and managed to munge up the following, which works.

DS> I'm sure Pastor Conway ran all the code in his book, so maybe something
DS> changed. Only Uri knows for sure.

DS> -jp

DS> #!/usr/bin/perl
DS> use strict; use warnings;

DS> use Sort::Maker;

DS> my @names = qw{ Fred Barney Wilma Betty };

DS> make_sorter(
DS> qw( ST ),
DS> name => 'sort_len',
DS> string => {
DS> code => sub { length }
DS> }
DS> ) or die "Unable to create sorter: $@";

DS> print join "\n", sort_len(@names);


from the Changes file:

0.04 Wed Apr 27 01:37:00 EDT 2005
- fixed 'name' option bug, added test and docs
-from Damian Conway <damian@conway.org>

so he found that bug and this was during the tech review period of PBP
so i think the fix didn't get propogated back to the book. in any case
you should always trust up to date docs in a module than any dead trees
book that mentions a module and shows examples on how to use it.

the best thing to do now is email damian and report this errata so he
could put it in his errata page and possibly get it fixed in a future
printing or edition.

uri

--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org

usenet@DavidFilmer.com 05-04-2006 08:43 AM

Re: Question re Conway's "Perl Best Practices" - Sort::Maker
 
Uri Guttman wrote:
> the best thing to do now is email Damian and report this errata


Thanks for your reply, Uri. I have submitted an errata report on the
O'Reilly website, as they provide an easy mechanism to facilitate this.

--
http://DavidFilmer.com


Randal L. Schwartz 05-04-2006 12:53 PM

Re: Question re Conway's "Perl Best Practices" - Sort::Maker
 
>>>>> "Uri" == Uri Guttman <uri@stemsystems.com> writes:

Uri> the best thing to do now is email damian and report this errata so he
Uri> could put it in his errata page and possibly get it fixed in a future
Uri> printing or edition.

Please don't "email the author" for an O'Reilly book to report errata.
O'Reilly's web page for a given book has a clearly marked "report and see
errata for this book" link. Use that instead.

Part of the services of a major publisher is to track and update errata, so
that the author does not need to do that directly. I'm surprised Uri was
unaware of that.

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

*** Posted via a free Usenet account from http://www.teranews.com ***

Salvador Fandino 05-04-2006 07:51 PM

Re: Question re Conway's "Perl Best Practices" - Sort::Maker
 
usenet@DavidFilmer.com wrote:
> Uri reminded me (in another thread: http://tinyurl.com/nyclh) of his
> module, Sort::Maker, which Damian Conway praised in "Perl Best
> Practices" (page 164-165), and which I have been meaning to learn more
> about.
>
> However, I am having difficulty with Damian's example.
>
> Kindly consider this small sample program wrapped around some PBP
> example code which I have retyped verbatum (adding only my own
> statement to populate sample @names):
>
> #!/usr/bin/perl
> use strict; use warnings;
> use Sort::Maker;
>
> my @names = qw{ Fred Barney Wilma Betty };
>
> make_sorter(name => 'sort_len', code => sub{ length }, ST => 1);
> # and later...
> my @names_shortest_first = sort_len(@names);
>
> __END__


you would probably want to have a look at Sort::Key module also. It is
usually faster than Sort::Maker and IMO easier to use.

For instance to sort by length:

use Sort::Key qw(ikeysort);

my @names = qw{ Fred Barney Wilma Betty };
my @names_shortest_first = ikeysort { length } @names;

or alternatively:

use Sort::Key::Maker sort_len => sub { length }, qw(integer);

my @names = qw{ Fred Barney Wilma Betty };
my @names_shortest_first = sort_len @names;

Cheers,

- Salva

Uri Guttman 05-04-2006 10:31 PM

Re: Question re Conway's "Perl Best Practices" - Sort::Maker
 
>>>>> "SF" == Salvador Fandino <sfandino@yahoo.com> writes:

SF> you would probably want to have a look at Sort::Key module also. It is
SF> usually faster than Sort::Maker and IMO easier to use.

i find the massive number of different exported functions, including
ones created on the fly to be more confusing. but timtowtdi rules apply.

as for faster, your module appears to do its key extractions and
compares in each compare block which are O(N log N). the GRT and ST
(both of which can be used in sort::maker) factor out the extractions
and makes them O(N) and that can be a major savings in large complex
sorts. so stating a module is usually faster than another should be
qualified with what criteria are used to compare them.

SF> For instance to sort by length:

SF> use Sort::Key qw(ikeysort);

SF> my @names = qw{ Fred Barney Wilma Betty };
SF> my @names_shortest_first = ikeysort { length } @names;

as i said above the multiple exported subs is not a style i like. also a
single exported sub with a well defined arg list can be more easily used
to autogenerated sort subs from a record description.

finally, sort::maker comes with a table driven test and benchmark
system. it should be easy for you to run it on your module and then we
can benchmark a wide range of datasets and sorts and see how the
different modules behave. i am very interested in seeing some apples to
apples results.

uri

--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org

Salvador Fandino 05-05-2006 08:51 AM

Re: Question re Conway's "Perl Best Practices" - Sort::Maker
 
Uri Guttman wrote:
>>>>>>"SF" == Salvador Fandino <sfandino@yahoo.com> writes:

>
>
> SF> you would probably want to have a look at Sort::Key module also. It is
> SF> usually faster than Sort::Maker and IMO easier to use.
>
> i find the massive number of different exported functions, including
> ones created on the fly to be more confusing. but timtowtdi rules apply.
>
> as for faster, your module appears to do its key extractions and
> compares in each compare block which are O(N log N).


No, keys are precomputed before sorting

> the GRT and ST
> (both of which can be used in sort::maker) factor out the extractions
> and makes them O(N) and that can be a major savings in large complex
> sorts. so stating a module is usually faster than another should be
> qualified with what criteria are used to compare them.


Sort::Key is faster than the ST or GRT sorting arrays of any lenght in
most cases. Only for some rare cases of key type combinations and data
could be the GRT a bit faster, but most of the times is the other way

> SF> For instance to sort by length:
>
> SF> use Sort::Key qw(ikeysort);
>
> SF> my @names = qw{ Fred Barney Wilma Betty };
> SF> my @names_shortest_first = ikeysort { length } @names;
>
> as i said above the multiple exported subs is not a style i like. also a
> single exported sub with a well defined arg list can be more easily used
> to autogenerated sort subs from a record description.


that functionality is also available from the Sort::Key::Maker module.
You can create new sorters on the fly just defining the types of the keys:

use Sort::Key::Maker my_sort => qw(number -number string);

my @sorted = my_sort { $_->{foo}, $_->{bar}, $_->{doz} } @data;


or alternatively you can attach the keys extraction sub to the sorter:

use Sort::Key::Maker my_sort =>
sub { $_->{foo}, $_->{bar}, $_->{doz} }
qw(number -number string);

my @sorted = my_sort @data;



> finally, sort::maker comes with a table driven test and benchmark
> system. it should be easy for you to run it on your module and then we
> can benchmark a wide range of datasets and sorts and see how the
> different modules behave. i am very interested in seeing some apples to
> apples results.


well, I already have some benchmark scripts of my own as for instance
the one attached:

$ for i in str num int num_str str_num; do perl ben2.pl -t $i; done

comparing sorters for str keys with 500000 elements:
s/iter sm skm sk
sm 6.58 -- -26% -28%
skm 4.85 36% -- -2%
sk 4.73 39% 3% --

comparing sorters for num keys with 500000 elements:
s/iter sm skm sk
sm 6.71 -- -71% -73%
skm 1.94 246% -- -5%
sk 1.84 265% 5% --

comparing sorters for int keys with 500000 elements:
s/iter sm skm sk
sm 5.94 -- -69% -70%
skm 1.85 221% -- -5%
sk 1.76 238% 5% --

comparing sorters for num_str keys with 500000 elements:
s/iter sm skm
sm 8.13 -- -31%
skm 5.62 45% --

comparing sorters for str_num keys with 500000 elements:
s/iter sm skm
sm 7.97 -- -35%
skm 5.17 54% --

(sm => Sort::Maker, sk => Sort::Key, skm => Sort::Key::Maker)

Cheers,

- Salvador



All times are GMT. The time now is 09:57 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.