#!/usr/bin/perl -w use strict; use Benchmark; #$ wc /usr/share/dict/words # 45424 45424 409276 /usr/share/dict/words my $file = '/usr/share/dict/words'; # These callbacks could do whatever you want. # They have the matching line passed in. sub foundThe { } sub foundAeig { } sub foundCat { } my %specs = ( '^the' => \&foundThe, 'at[ei]g' => \&foundAeig, 'cat$' => \&foundCat, ); my %cookedSpecs = map { qr{$_}, $specs{$_} } keys(%specs); sub usingForeach { $count = 0; open FILE, $file or die "can't open $file: $!\n"; while () { foreach my $pattern ( keys(%cookedSpecs) ) { if (m{$pattern}) { $cookedSpecs{$pattern}->($_); } } } close FILE; } sub usingAlternates { my $altpattern = join ( '|', map {qr{$_}} keys(%specs) ); $count = 0; open FILE, $file or die "can't open $file: $!\n"; while () { if (m{$altpattern}) { foreach my $pattern ( keys(%cookedSpecs) ) { if (m{$pattern}) { $cookedSpecs{$pattern}->($_); } } } } close FILE; } Benchmark::cmpthese( -30, { 'using foreach' => \&usingForeach, 'using alternates' => \&usingAlternates } );