Hi Monks,
There are many ways to solve a question "Is this element in the list?" It doesn't matter how the way you chosen if a list is small. But choosing the right way is very important if a list is huge.
Looking for the fastest method I've made benchmarks for some of them. Now I can say that there are two best ways exist. They are based on foreach & grep.
#... grep_line => sub { grep { $_ eq TEST and return 1 } @Array; return; }, for_line => sub { TEST eq $_ and return 1 foreach @Array; return; } #...
As Abigail-II said, foreach wins when a match occcures in the first one-third of an array but grep better when a match occcures in the last one-third.
P.S. I did not consider map because I don't beleive that it could be better than grep.
UPDATE: 4 Oct 2004, I've compared a List::Util::first function with "grep_line" and "for_line". I found that List::Util::first is slower.
#!/usr/bin/perl -w use strict; use Benchmark; use constant TEST => 'match'; use constant SIZE => 100000; my @pos = (0.05, 0.1, 0.2, 0.4, 0.6, 0.8, 0.9); my @Array; my %subs = ( grep_block => sub { GREP: { grep { $_ eq TEST and next GREP } @Array; return; } continue { return 1; } }, grep_line => sub { grep { $_ eq TEST and return 1 } @Array; return; }, grep_simple => sub { return grep { $_ eq TEST } @Array; }, for_block => sub { foreach (@Array) { return 1 if TEST eq $_; } return; }, for_line => sub { TEST eq $_ and return 1 foreach @Array; return; } ); foreach (@pos) { my $pos = SIZE * $_; printf "Matching position %d from %d i.e. (%0.2f)\n" , $pos, SIZE + , $pos/SIZE; @Array = ( ('x') x ($pos - 1), TEST, ('x') x (SIZE - $pos) ); Benchmark::cmpthese( 1000, \%subs ); }
Matching position 5000 from 100000 i.e. (0.05) Benchmark: timing 1000 iterations of for_block, for_line, grep_block, grep_line, grep_simple... Rate grep_simple grep_block grep_line for_block for_line grep_simple 11.1/s -- -79% -91% -95% -95% grep_block 52.3/s 372% -- -60% -75% -77% grep_line 130/s 1073% 148% -- -39% -44% for_block 212/s 1814% 305% 63% -- -8% for_line 231/s 1983% 341% 78% 9% -- Matching position 10000 from 100000 i.e. (0.10) Benchmark: timing 1000 iterations of for_block, for_line, grep_block, grep_line, grep_simple... Rate grep_simple grep_block grep_line for_block for_line grep_simple 11.1/s -- -60% -86% -88% -89% grep_block 28.0/s 153% -- -65% -70% -73% grep_line 80.6/s 628% 187% -- -15% -21% for_block 94.8/s 756% 238% 18% -- -8% for_line 103/s 827% 266% 27% 8% -- Matching position 20000 from 100000 i.e. (0.20) Benchmark: timing 1000 iterations of for_block, for_line, grep_block, grep_line, grep_simple... Rate grep_simple grep_block grep_line for_block for_line grep_simple 11.1/s -- -24% -76% -76% -78% grep_block 14.5/s 31% -- -68% -69% -71% grep_line 45.6/s 312% 214% -- -1% -9% for_block 46.3/s 318% 219% 1% -- -8% for_line 50.1/s 352% 245% 10% 8% -- Matching position 40000 from 100000 i.e. (0.40) Benchmark: timing 1000 iterations of for_block, for_line, grep_block, grep_line, grep_simple... Rate grep_block grep_simple for_block grep_line for_line grep_block 7.38/s -- -33% -68% -70% -71% grep_simple 11.1/s 50% -- -52% -55% -56% for_block 23.2/s 214% 109% -- -5% -7% grep_line 24.5/s 231% 121% 6% -- -2% for_line 25.1/s 239% 126% 8% 2% -- Matching position 60000 from 100000 i.e. (0.60) Benchmark: timing 1000 iterations of for_block, for_line, grep_block, grep_line, grep_simple... Rate grep_block grep_simple for_block grep_line for_line grep_block 4.96/s -- -55% -68% -70% -70% grep_simple 11.1/s 123% -- -28% -34% -34% for_block 15.5/s 212% 40% -- -7% -7% grep_line 16.7/s 237% 51% 8% -- -0% for_line 16.7/s 237% 51% 8% 0% -- Matching position 80000 from 100000 i.e. (0.80) Benchmark: timing 1000 iterations of for_block, for_line, grep_block, grep_line, grep_simple... Rate grep_block grep_simple for_block for_line grep_line grep_block 3.73/s -- -66% -68% -70% -70% grep_simple 11.1/s 197% -- -4% -12% -12% for_block 11.6/s 211% 5% -- -7% -8% for_line 12.5/s 236% 13% 8% -- -0% grep_line 12.6/s 237% 14% 9% 0% -- Matching position 90000 from 100000 i.e. (0.90) Benchmark: timing 1000 iterations of for_block, for_line, grep_block, grep_line, grep_simple... Rate grep_block for_block for_line grep_simple grep_line grep_block 3.31/s -- -67% -70% -70% -71% for_block 10.2/s 208% -- -8% -8% -10% for_line 11.0/s 233% 8% -- -0% -2% grep_simple 11.1/s 234% 9% 0% -- -2% grep_line 11.3/s 242% 11% 2% 2% --
|
---|