Hi All,

So, speaking of the Schwarzian transform, I've recently wanted to do a
similar transform, not for sorting, but for grepping.

I'm using String::Approx to restrict a list of strings.  The matching
routine runs fastest when it's given the entire list of strings.
Unfortunately, the data I have (the result set of an SQL query) is usually
a list of hashrefs, and I want to apply the matching function to one of
the values in the hashref, getting back a subset of the original list.

My test program is below -- I'd love to hear of better ways to
approach the problem.

-Brian

------------------------------------------------------------------
use String::Approx 'amatch';
use Benchmark::Timer;
use Data::Dumper;

$t = new Benchmark::Timer;

# Sample data structure; we'll look for matching entries where
# the "info" tag matches '3456'.
@list = map { +{ 'info' => sprintf("%09d",$_),
                 'id' => "id #".(int rand 100) } } (1..10000);

# Method 1 : straightforward grep
$t->start('grepping');
@found1 = grep { amatch('3456',$_->{'info'}) } @list;
$t->stop;

# Method 2 : make a hash, match the keys, untransform
$t->start('transforming');
for my $i (0..$#list) {
    $hash{$list[$i]->{'info'}} ||= [];
    push @{$hash{$list[$i]->{'info'}}}, $i;
}
@foundkeys = amatch('3456',keys %hash);
@foundindexes = map {@$_} @hash{@foundkeys};
@found2 = @list[sort {$a<=>$b} @foundindexes];
$t->stop;

print "different" unless Dumper(\@found1) eq Dumper(\@found2);

$t->report;

# 1 trial of grepping (231.910ms total)
# 1 trial of transforming (72.333ms total)


Reply via email to