P:\test>273557.pl8 14: 462 15: 684 19: 898 21: 15 1892 22: 1997 41: 223 43: 762 45: 668 46: 1759 54: 1962 56: 509 61: 1497 68: 1006 69: 342 349 70: 565 75: 845 84: 1318 92: 382 99: 315 #### P:\test>273557.pl8 P:\test>273557.pl8 14: 462 15: 684 19: 898 21: 15 1892 22: 1997 41: 223 43: 762 45: 668 46: 1759 54: 1962 56: 509 61: 1497 68: 1006 69: 342 349 70: 565 75: 845 84: 1318 92: 382 99: 315 #### P:\test>273557.pl8 14: 462 15: 684 19: 898 21: 15 1892 22: 1997 41: 223 43: 762 45: 668 46: 1759 54: 1962 56: 509 61: 1497 68: 1006 69: 342 349 70: 565 75: 845 84: 1318 92: 382 99: 315 #### P:\test>273557.pl8 14: 462 15: 684 19: 898 21: 15 1892 22: 1997 41: 223 43: 762 45: 668 46: 1759 54: 1962 56: 509 61: 1497 68: 1006 69: 342 349 70: 565 75: 845 84: 1318 92: 382 99: 315 #### P:\test>273557.pl8 14: 462 15: 684 19: 898 21: 15 1892 22: 1997 41: 223 43: 762 45: 668 46: 1759 54: 1962 56: 509 61: 1497 68: 1006 69: 342 349 70: 565 75: 845 84: 1318 92: 382 99: 315 #### P:\test>273557.pl8 14: 462 15: 684 19: 898 21: 15 1892 22: 1997 41: 223 43: 762 45: 668 46: 1759 54: 1962 56: 509 61: 1497 68: 1006 69: 342 349 70: 565 75: 845 84: 1318 92: 382 99: 315 #### #! perl -sw use strict; use Benchmark::Timer; use vars qw[$SEED]; # We'll pass it as ref to SCALAR and receive it in a ref to ARRAY use constant ARTICLES => 100; use constant ENTRIES => 2000; my $t = Benchmark::Timer->new(); srand( $S || 1 ); $t->start('Using scalar grep to count occurances'); my( @A, @E, %X ); my( %A ); #Articles foreach my $article ( 1 .. ARTICLES ) { foreach my $feature ( 1 .. 10 ) { $A[$article][$feature] = int rand(100); } } #Entries foreach my $entry ( 1 .. ENTRIES ) { foreach my $feature ( 1 .. 10 ) { $E[$entry][$feature] = int rand(100); } } $| += 1; foreach my $article ( 1 .. ARTICLES ) { foreach my $entry ( 1 .. ENTRIES ) { my $count = grep{ $E[$entry][$_] eq $A[$article][$_] } 1 .. 10; push @{ $X{$article} }, $entry if $count >= 3; } } foreach my $article ( sort { $a <=> $b } keys %X ) { print "$article:"; foreach my $entry ( @{ $X{$article} } ) { print "\t$entry"; } print "\n"; } $t->stop('Using scalar grep to count occurances'); $t->report; #### #! perl -slw use strict; use Benchmark::Timer; use vars qw[$SEED]; use constant ARTICLES => 100; use constant ENTRIES => 2000; $| += 1; sub uniq{ my %h; @h{ @_ } = (); return keys %h; } # return a list of all the combinations of n (1st param) values # from r (the rest of the argument list). sub Cnr{ my( $n, @r ) = shift; return [] unless $n--; for my $x ( 0 .. ($#_ - $n) ) { push @r, map{ [ $_[$x], @$_ ] } Cnr( $n, @_[ ($x + 1) .. $#_ ] ) ; } return @r; } my $t = Benchmark::Timer->new(); srand( $SEED || 1 ); $t->start('Building an using a lookup list'); my( @A, @E, %X ); my( %A ); my @combs = Cnr( 3, 1 .. 10 ); #Articles for my $article ( 1 .. ARTICLES ) { for my $feature ( 1 .. 10 ) { $A[$article][$feature] = int rand(100); } push @{ $A{ "@$_:@{ $A[$article] }[ @$_ ]" } }, $article for @combs; } # print "$_ : @{ $A[$_] }[ 1 .. 10 ]" for 1 .. ARTICLES; #Entries for my $entry ( 1 .. ENTRIES ) { for my $feature ( 1 .. 10 ) { $E[$entry][$feature] = int rand(100); } } # print "$_ : @{ $E[$_] }[ 1 .. 10 ]" for 1 .. ENTRIES; for my $entry ( 1 .. ENTRIES ) { for my $comb ( map{ "@$_:@{ $E[ $entry ] }[ @$_ ]" } @combs ) { next unless exists $A{ $comb }; push @{ $X{ $_ } }, $entry for @{ $A{ $comb } }; } } for my $article ( sort { $a <=> $b } keys %X ) { printf STDERR "$article:"; for my $entry ( @{ $X{$article} } ) { printf STDERR "\t$entry"; } print STDERR ''; } $t->stop('Building an using a lookup list'); $t->report; __OUTPUT__ P:\test>273557 14: 462 15: 684 19: 898 21: 15 1892 22: 1997 41: 223 43: 762 762 762 762 (*) 45: 668 46: 1759 54: 1962 56: 509 61: 1497 68: 1006 69: 342 349 70: 565 75: 845 84: 1318 92: 382 99: 315 1 trial of Building an using a lookup list (10.705s total) #### time(s) original array/grep lookup original 414.536 ---- -64% -93% array/grep 149.685 177% ---- -81% lookup 27.750 1394% 439% ---- #### for my $entry ( @{ $X{$article} } ) { #### for my $entry ( uniq @{ $X{$article} } ) {