Now before I go further lets deal with the 'If you want fast then you shouldn't be using Perl, use C' objections. Crap. That kind of logic would lead someone who has just discovered that their Perl bubblesort implementation is too slow to rwrite it in C, instead of doing the obvious and using perls built in sort. Why would I want to use code that is twice as slow as code that is just is easy to write in the same language?? Sure if overall kickass speed was the bottom line I wouldnt use Perl. But being aware of and taking advantage of the optimizations that Perl allows isn't wrong, its smart.
The next is the inappropriate use of grep and map. grep seems to be the ideal subject for abuse. Lots of people seem to think of it as an 'element finder'. Uh, No. Its a filter. The idea is for it to be used on lots of elements to find subsets of the original elements, normally more than one. There are _much_ more efficient ways of finding a single element in an array. map() is abused in a similar way. It is NOT a for loop. Ok, if you're writing an obfu, or you _really_ dont care about speed then fine use map or grep. But its a piece of shorthand that should be used only rarely, that is when you need to transform most elements from one array into a different set of elements in a new array. Incidentally if you decide to use map or grep in void context then grep seems to be faster.
So heres what to keep in mind:
Now this all applies to 5.6, I'd be interested in knowing how it differs from earlier version.use Benchmark 'cmpthese'; our $n=10; our $sum=0; cmpthese (-5,{ 'grep{}' => '$sum=0; grep {$sum+=$_} 0..$n;', 'grep()' => '$sum=0; grep ($sum+=$_,0..$n);', 'map{}' => '$sum=0; map {$sum+=$_} 0..$n;', 'map()' => '$sum=0; map ($sum+=$_,0..$n);', 'for_modif' => '$sum=0; $sum+=$_ foreach 0..$n;', 'foreach' => '$sum=0; foreach my $i (0..$n) {$sum+=$i} +', 'for(;;)3' => '$sum=0; for (my $i=0;$i<=$n;$i++) {$sum+ +=$i}', 'for(;;)2' => '$sum=0; for (my $i=0;$i++<=$n;) {$sum+=$ +i}', 'w{}c{}' => '$sum=0; my $i=0; while($i<=$n){$sum+=$i} +continue{$i++}', 'while' => '$sum=0; my $i=0; while($i<=$n){$sum+=$i+ ++};', }); __END__ #last two columns removed for space reasons Rate map{} grep{} map() for(;;)3 w{}c{} grep() for(;;)2 w +hile map{} 39416/s -- -3% -21% -34% -34% -41% -45% +-47% grep{} 40750/s 3% -- -18% -32% -32% -39% -44% +-46% map() 49897/s 27% 22% -- -16% -17% -25% -31% +-33% for(;;)3 59526/s 51% 46% 19% -- -0% -11% -18% +-21% w{}c{} 59804/s 52% 47% 20% 0% -- -10% -17% +-20% grep() 66614/s 69% 63% 34% 12% 11% -- -8% +-11% for(;;)2 72308/s 83% 77% 45% 21% 21% 9% -- + -4% while 75007/s 90% 84% 50% 26% 25% 13% 4% + -- foreach 80124/s 103% 97% 61% 35% 34% 20% 11% + 7% for_modif 84073/s 113% 106% 68% 41% 41% 26% 16% + 12%
Anyway, I suppose this is a bit of a rant, but its something that has gotten to me a bit lately, especially respected members of our community posting what I consider to be 'clever but BS' solutions to problems. To me if a solution is not as effecient as is reasonable then it shouldnt be posted.
:-)
Yves
--
You are not ready to use symrefs unless you already know why they are bad. -- tadmc (CLPM)
In reply to Efficient Looping Constructs by demerphq
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |