FAST::List::Gen::Benchmark - performance tips for using FAST::List::Gen
this document contains various benchmarks comparing the parallel syntax styles that FAST::List::Gen provides.
perl -MFAST::List::Gen::Benchmark
iteration: reduce: my $x = $gen->reduce(sub {$a + $b}); # same as $gen->sum do: my $x; $gen->do(sub {$x += $_}) for: my $x; $x += $_ for @$gen; more/next: my $x; $gen->reset; $x += $gen->next while $gen->more; $gen->(): my ($x, $n); $gen->reset; $x += $n while ($n) = $gen->(); iterator: my $it = $gen->iterator; my ($x, $n); $gen->reset; $x += $n while ($n) = $it->(); next: my ($x, $n); $gen->reset; $x += $n while ($n) = $gen->next; handle: my $x; local $_; $gen->reset; $x += $_ while <$gen>;
iteration: [+] 0 .. 10: Rate reduce do for more/next $gen->() iterator next handle reduce 28489/s -- -8% -30% -55% -55% -67% -68% -71% do 31109/s 9% -- -24% -51% -51% -64% -65% -69% for 40877/s 43% 31% -- -35% -35% -53% -55% -59% more/next 62977/s 121% 102% 54% -- -0% -27% -30% -36% $gen->() 63141/s 122% 103% 54% 0% -- -27% -30% -36% iterator 86340/s 203% 178% 111% 37% 37% -- -4% -13% next 90021/s 216% 189% 120% 43% 43% 4% -- -9% handle 98964/s 247% 218% 142% 57% 57% 15% 10% -- [+] 0 .. 50: Rate for $gen->() more/next reduce do next iterator handle for 8762/s -- -40% -40% -41% -43% -59% -60% -63% $gen->() 14546/s 66% -- -1% -2% -5% -31% -34% -38% more/next 14646/s 67% 1% -- -2% -4% -31% -33% -38% reduce 14892/s 70% 2% 2% -- -3% -30% -32% -37% do 15278/s 74% 5% 4% 3% -- -28% -30% -35% next 21222/s 142% 46% 45% 43% 39% -- -3% -10% iterator 21892/s 150% 51% 49% 47% 43% 3% -- -7% handle 23454/s 168% 61% 60% 57% 54% 11% 7% -- [+] 0 .. 100: Rate for more/next $gen->() reduce do next iterator handle for 4424/s -- -40% -42% -53% -53% -60% -61% -64% more/next 7385/s 67% -- -3% -21% -21% -34% -34% -39% $gen->() 7607/s 72% 3% -- -19% -19% -32% -32% -38% reduce 9340/s 111% 26% 23% -- -0% -16% -17% -23% do 9341/s 111% 26% 23% 0% -- -16% -17% -23% next 11108/s 151% 50% 46% 19% 19% -- -1% -9% iterator 11253/s 154% 52% 48% 20% 20% 1% -- -8% handle 12190/s 176% 65% 60% 31% 31% 10% 8% -- [+] 0 .. 1000: Rate for more/next $gen->() next iterator do reduce handle for 446/s -- -39% -42% -61% -62% -62% -63% -64% more/next 735/s 65% -- -4% -35% -37% -37% -39% -41% $gen->() 763/s 71% 4% -- -33% -34% -34% -37% -38% next 1131/s 153% 54% 48% -- -3% -3% -7% -9% iterator 1164/s 161% 58% 52% 3% -- -0% -4% -6% do 1165/s 161% 58% 53% 3% 0% -- -4% -6% reduce 1210/s 171% 65% 58% 7% 4% 4% -- -2% handle 1237/s 177% 68% 62% 9% 6% 6% 2% -- [+] 0 .. 10000: Rate for more/next $gen->() next iterator do handle reduce for 44.5/s -- -40% -42% -60% -62% -63% -64% -64% more/next 74.0/s 66% -- -3% -34% -36% -39% -41% -41% $gen->() 76.6/s 72% 4% -- -32% -34% -37% -38% -39% next 113/s 153% 52% 47% -- -3% -8% -9% -10% iterator 116/s 161% 57% 52% 3% -- -5% -7% -7% do 122/s 174% 65% 59% 8% 5% -- -2% -3% handle 124/s 179% 68% 62% 10% 7% 2% -- -1% reduce 125/s 182% 70% 64% 11% 8% 3% 1% -- [+] 0 .. 100000: Rate for more/next $gen->() next iterator reduce do handle for 4.47/s -- -41% -42% -61% -62% -63% -64% -64% more/next 7.55/s 69% -- -2% -34% -36% -38% -39% -40% $gen->() 7.71/s 72% 2% -- -32% -35% -36% -38% -39% next 11.4/s 155% 51% 48% -- -4% -6% -8% -9% iterator 11.9/s 166% 57% 54% 4% -- -2% -4% -5% reduce 12.1/s 170% 60% 57% 6% 2% -- -2% -4% do 12.3/s 176% 64% 60% 8% 4% 2% -- -2% handle 12.5/s 180% 66% 63% 10% 6% 4% 2% --
once the generator size gets large enough to mask differences in initialization code, the access methods fall into 4 classes.
for
while it is one of the most perlish ways to write the loop, the $x += $_ for @$gen construct uses a tied array, and unfortunately ties are fairly slow. all of the other constructs use the exact same underlying FETCH and FETCHSIZE methods that the tied array uses, yet they are all much faster.
$x += $_ for @$gen
FETCH
FETCHSIZE
more/next, $gen->()
these are almost the same speed, and are the slowest of the non-tied access methods. the more/next pair results in unneeded function calls, since next is checking the more condition already. the overloaded dereference has some interpreter overhead.
more/next
next
more
next, iterator, reduce, do
these are the faster ways to access generators, the ranking of which depends on the size of the generator. next and iterator are almost the same, and are fast across the size range. iterator will always be slightly faster than next since it is the function used internally by next
iterator
reduce and do both have slower start-up time than next or iterator due to a bit of initialization code. this initialization code allows for their loops to be optimized further, which lets reduce and do achieve higher speeds for larger generators.
reduce
do
handle
handle iteration in a while loop is heavily optimized by perl, and is subsequently one of the fastest techniques for iterating over a generator, and this speed is independent of generator size.
in summary, stick to next, iterator, reduce, do, or handle iteration styles if performance is a concern.
next, iterator, reduce, do, or handle
Eric Strom, <asg at cpan.org>
<asg at cpan.org>
copyright 2009-2011 Eric Strom.
this program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
see http://dev.perl.org/licenses/ for more information.
To install FAST, copy and paste the appropriate command in to your terminal.
cpanm
cpanm FAST
CPAN shell
perl -MCPAN -e shell install FAST
For more information on module installation, please visit the detailed CPAN module installation guide.