tholbroo
had mentioned to me that if I'm doing a regular sort
on Class::DBI objects, I can save a lot of time by doing a Schwartzian transform. I didn't think that there would be much of a penalty on small sets, but I decided to do some benchmarking (using the CPANTS DB):
package CPANTS::Distro::Kwalitee; use strict; use warnings; use base qw( Class::DBI ); __PACKAGE__->connection( 'dbi:SQLite:dbname=cpants.db' ); __PACKAGE__->table( 'kwalitee' ); __PACKAGE__->columns( All => qw( distid kwalitee extractable extracts_nicely has_buildtool has_manifest has_meta_yml has_proper_version has_readme has_test_pod has_test_pod_coverage has_tests has_version is_prereq no_cpants_errors no_pod_errors no_symlinks proper_libs use_strict ) ); package main; use strict; use warnings; use Benchmark qw( cmpthese ); my @distros = CPANTS::Distro::Kwalitee->retrieve_all; @distros = @distros[ 0..99 ]; printf( "Sorting %d rows...\n", scalar @distros ); cmpthese( 1000, { regular_sort => \®ular_sort, schwartz_sort => \&schwartz_sort } ); sub regular_sort { @distros = sort { $a->kwalitee <=> $b->kwalitee } @distros; } sub schwartz_sort { @distros = map { $_->[ 0 ] } sort { $a->[ 1 ] <=> $b->[ 1 ] } map { [ $_, $_->kwalitee ] } @distros; } __END__ C:\cdbibench>perl bench.pl Sorting 100 rows... Rate regular_sort schwartz_sort regular_sort 102/s -- -47% schwartz_sort 195/s 90% --
Interesting. tholbroo
++
Class::DBI considered a hinderance
Aristotle on 2005-04-03T00:38:28
Yeah, what autarch said.
This is why gave up Class::DBI – it very nearly forces you to do on the Perl side what should be done at the SQL level because it makes it way too difficult to do the latter. First you run into a wall of no documentation, then you often have to put up with annoying verbiage. After reading the source for 15 minutes, I think the following will do what you need:
CPANTS::Distro::Kwalitee->set_sql(
all_by_kwalitee => 'SELECT __ESSENTIAL__ FROM __TABLE__ ORDER BY kwalitee',
);
my @distros = CPANTS::Distro::Kwalitee->sth_to_objects( 'all_by_kwalitee' );Note that
sth_to_objects()
is not documented anywhere. The code should work, but I cannot tell since I’m not going to spend another 15 minutes setting up all the knobs and handles that testing Class::DBI code requires. If it does not work, the least-effort approach will require more red tape. Compare to plain DBI to get an AoH, which is clearly documented and took me 40 seconds to write:my $distros = $dbh->selectall_arrayref( 'SELECT * FROM kwalitee ORDER BY kwalitee', { Slice => {} } );Plain DBI is at times crufty, but at least it doesn’t get in your way. As a bonus, it has much less overhead. Class::DBI is seductive, and will whisper in your ear that you that you don’t need to get your hands dirty with all that SQL, but in practice I’ve found it fails to deliver. Last not least, Class::DBI’s dependencies are legion.