Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re^5: C-style for loop

by ccn (Vicar)
on Nov 15, 2008 at 22:01 UTC ( [id://723853]=note: print w/replies, xml ) Need Help??


in reply to Re^4: C-style for loop
in thread C-style for loop

#!/usr/bin/perl -- use strict; use warnings; use Benchmark qw(cmpthese); my $BIG = 100_000; cmpthese(1000, { 'C-style' => \&c, 'P-style' => \&p}); sub c { for (my $i = $BIG; $i > 0; $i--) { 1; } } sub p { for my $i ( reverse 1..$BIG ) { 1; } } __END__ Rate P-style C-style P-style 26.7/s -- -44% C-style 48.0/s 80% --

Is Perl-style still better?

Replies are listed 'Best First'.
Re^6: C-style for loop
by GrandFather (Saint) on Nov 15, 2008 at 23:08 UTC

    Absolutely if the point you are trying to make is that there is a tiny execution penalty in this rather artificial case for using the Perl style for loop. An interesting test is to change the loops from reverse to forwards and see where the differences lie. For the C style for loop you need to change every part of the loop header in a major way and you have to think a while to ensure the range is what you want:

    for (my $i = $BIG; $i > 0; $i--) { becomes for (my $i = 0; $i <= $BIG; $i++) {

    For the Perl loop just deleting the reverse does the trick and the range is still completely clear. Oh, and now the Perl loop overhead is less than the C loop overhead:

    #!/usr/bin/perl -- use strict; use warnings; use Benchmark qw(cmpthese); my $BIG = 100_000; print "c: ", c (),"\n"; print "p: ", p (),"\n"; print "cF: ", cF (),"\n"; print "pF: ", pF (),"\n"; cmpthese(-1, { 'C-style' => \&c, 'P-style' => \&p, 'C-styleF' => \&cF, 'P-styleF' => \&pF, }); sub c { my $sum = 1; for (my $i = $BIG; $i > 0; $i--) { $sum += $i; } return $sum; } sub p { my $sum = 1; for my $i ( reverse 1..$BIG ) { $sum += $i; } return $sum; } sub cF { my $sum = 1; for (my $i = 1; $i <= $BIG; $i++) { $sum += $i; } return $sum; } sub pF { my $sum = 1; for my $i ( 1..$BIG ) { $sum += $i; } return $sum; } __END__ c: 5000050001 p: 5000050001 cF: 5000050001 pF: 5000050001 Rate P-style C-style C-styleF P-styleF P-style 49.9/s -- -23% -33% -42% C-style 65.0/s 30% -- -13% -25% C-styleF 74.7/s 50% 15% -- -13% P-styleF 86.2/s 73% 33% 15% --

    Considering how small the overhead of using reverse is and how much more maintainable the Perl loop is you have done an admirable job of demonstrating why in the general case the Perl for loop is much better than the C style for loop.


    Perl reduces RSI - it saves typing
Re^6: C-style for loop
by ikegami (Patriarch) on Nov 16, 2008 at 01:42 UTC
    • For for (X..Y), Perl uses a counting loop.
    • For for (reverse constX..constY), Perl builds a flattened list at compile-time and iterates over it in reverse.
    • For for (reverse X..Y), Perl builds a flattened list at run-time and iterates over it in reverse.

    So far, I've found 6 different kinds of for loops in Perl. You can find them in an earlier node.

    #!/usr/bin/perl -- use strict; use warnings; use Benchmark qw(cmpthese); my $BIG = 100_000; cmpthese(-3, { c_f => \&c_f, c_r => \&c_r, p_fv => \&p_fc, p_fc => \&p_fv, p_rc => \&p_rc, p_rv => \&p_rv, }); sub c_f { for (my $i = 0; $i < $BIG; $i++ ) { 1 } } sub c_r { for (my $i = $BIG; $i-- > 0; ) { 1 } } sub p_fc { for my $i ( 0..100_000-1 ) { 1 } } sub p_fv { for my $i ( 0..$BIG-1 ) { 1 } } sub p_rc { for my $i ( reverse 0..100_000-1 ) { 1 } } sub p_rv { for my $i ( reverse 0..$BIG-1 ) { 1 } } __END__ Rate p_rv c_r c_f p_rc p_fv p_fc p_rv 28.5/s -- -37% -44% -59% -64% -65% Builds list and loops. c_r 45.0/s 58% -- -11% -35% -44% -44% c_f 50.7/s 78% 13% -- -27% -37% -37% p_rc 69.7/s 144% 55% 37% -- -13% -14% Loops over pre-built array. p_fv 80.0/s 180% 78% 58% 15% -- -1% Counting loop p_fc 80.7/s 183% 79% 59% 16% 1% -- Counting loop

    If you add "()," to the front of any of the lists, you'll notice that p_* will become as slow as p_rv.

Re^6: C-style for loop
by zwon (Abbot) on Nov 15, 2008 at 23:00 UTC
    It depends
    #!/usr/bin/perl -- use strict; use warnings; use Benchmark qw(cmpthese); my $BIG = 100_000; cmpthese( 1000, { 'C-style' => \&c, 'P-style' => \&p } ); sub c { for ( my $i = 1 ; $i <= $BIG ; $i++ ) { 1; } } sub p { for ( 1 .. $BIG ) { 1; } } __END__ Rate C-style P-style C-style 141/s -- -29% P-style 200/s 42% --

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://723853]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (7)
As of 2024-03-28 10:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found