post increment or pre increment?

Discussion in 'Perl Misc' started by Peng Yu, Nov 21, 2008.

  1. Peng Yu

    Peng Yu Guest

    Hi,

    I learned in C++, that it is better to use pre increment rather than
    post increment. I'm wondering which one is better to use in perl, for
    example, in a for loop.

    for(my $i = 0; $i <10; ++ $i)

    or

    for(my $i = 0; $i <10; $i ++)

    Which one is better?

    Thanks,
    Peng
     
    Peng Yu, Nov 21, 2008
    #1
    1. Advertising

  2. Peng Yu

    Guest

    On Thu, 20 Nov 2008 20:23:30 -0800 (PST), Peng Yu <> wrote:

    >Hi,
    >
    >I learned in C++, that it is better to use pre increment rather than
    >post increment. I'm wondering which one is better to use in perl, for
    >example, in a for loop.
    >
    >for(my $i = 0; $i <10; ++ $i)
    >
    >or
    >
    >for(my $i = 0; $i <10; $i ++)
    >
    >Which one is better?
    >
    >Thanks,
    >Peng

    I think the same rules apply. I never use pre increment
    in general.

    But you would never do something like a function lvalue in C++:
    if (func() == 5)...
    better this
    if (5 == func())


    sln
     
    , Nov 21, 2008
    #2
    1. Advertising

  3. Peng Yu <> wrote:
    >Hi,
    >
    >I learned in C++, that it is better to use pre increment rather than
    >post increment. I'm wondering which one is better to use in perl,


    It depends on what you want to do. In that expression, do you need the
    old value before the increment or the new value after the increment?

    >example, in a for loop.
    >
    >for(my $i = 0; $i <10; ++ $i)
    >
    >or
    >
    >for(my $i = 0; $i <10; $i ++)
    >
    >Which one is better?


    Neither, nor. The best is a very simple and much more readable

    for my $i (0..9)

    jue
     
    Jürgen Exner, Nov 21, 2008
    #3
  4. writes:

    > But you would never do something like a function lvalue in C++:
    > if (func() == 5)...
    > better this
    > if (5 == func())


    These examples has nothing to do with lvalue functions and are
    equivalent as long as we're not dealing with overloading of the
    equality operator.

    Lvalue functions is all about assignments and only assignments.

    //Makholm
     
    Peter Makholm, Nov 21, 2008
    #4
  5. Peng Yu

    Tim Greer Guest

    Peng Yu wrote:

    > Hi,
    >
    > I learned in C++, that it is better to use pre increment rather than
    > post increment. I'm wondering which one is better to use in perl, for
    > example, in a for loop.
    >
    > for(my $i = 0; $i <10; ++ $i)
    >
    > or
    >
    > for(my $i = 0; $i <10; $i ++)
    >
    > Which one is better?
    >
    > Thanks,
    > Peng


    Which is better, depends on your needs. Do you want to pre or post
    increment in your loop? You don't have to pre/post increment, when you
    can use other functions to loop x number of times either.
    --
    Tim Greer, CEO/Founder/CTO, BurlyHost.com, Inc.
    Shared Hosting, Reseller Hosting, Dedicated & Semi-Dedicated servers
    and Custom Hosting. 24/7 support, 30 day guarantee, secure servers.
    Industry's most experienced staff! -- Web Hosting With Muscle!
     
    Tim Greer, Nov 21, 2008
    #5
  6. On 2008-11-21 05:32, Jürgen Exner <> wrote:
    > Peng Yu <> wrote:
    >>I learned in C++, that it is better to use pre increment rather than
    >>post increment. I'm wondering which one is better to use in perl,

    >
    > It depends on what you want to do. In that expression, do you need the
    > old value before the increment or the new value after the increment?


    In the example he gave, he needs neither the old nor the new value. He
    just needs the side effect. This is very common in C and C++, and the
    only case where you pre- and postincrement are semantically equivalent,
    so you can choose one or the other.

    Pre-increment is semantically simpler. It increments the variable and
    returns the new value. Post-increment needs to save the old value before
    incrementing the variable, so that it can return the old value.

    For simple variables this doesn't make any difference in C++, since the
    compiler can just optimize the copy away. But for objects, it's not so
    simple (the copy itself may cause some side-effect) so the usual advice
    is to use pre-increment if you don't need the return value.

    Perl has a very weak optimizer (because it needs to be fast), so
    pre-increment might be faster.

    >>example, in a for loop.
    >>
    >>for(my $i = 0; $i <10; ++ $i)
    >>
    >>or
    >>
    >>for(my $i = 0; $i <10; $i ++)
    >>
    >>Which one is better?


    Why don't you just try it?

    > Neither, nor. The best is a very simple and much more readable
    >
    > for my $i (0..9)


    #!/usr/bin/perl
    use warnings;
    use strict;
    use Benchmark qw(cmpthese);

    use constant N => 10;

    cmpthese (-5,
    {
    'pre' => sub { for(my $i = 0; $i <N; ++ $i) {} },
    'post' => sub { for(my $i = 0; $i <N; ++ $i) {} },
    'range' => sub { for my $i (0 .. N-1) {} },
    });
    __END__

    Oops, the range is consistently the slowest:

    Rate range post pre
    range 667769/s -- -7% -7%
    post 714756/s 7% -- -1%
    pre 721696/s 8% 1% --

    Rate range post pre
    range 634634/s -- -8% -9%
    post 691932/s 9% -- -0%
    pre 694498/s 9% 0% --

    Rate range post pre
    range 636271/s -- -14% -19%
    post 739517/s 16% -- -6%
    pre 786373/s 24% 6% --

    but let's try N => 100:

    Rate pre post range
    pre 103353/s -- -0% -27%
    post 103859/s 0% -- -27%
    range 141336/s 37% 36% --

    Rate post pre range
    post 91995/s -- -8% -34%
    pre 100124/s 9% -- -28%
    range 140021/s 52% 40% --

    Rate post pre range
    post 96837/s -- -7% -31%
    pre 103855/s 7% -- -26%
    range 140913/s 46% 36% --

    Now, using a range is the fastest version, and that advantage increases for larger loops:

    N => 1000:

    Rate pre post range
    pre 10094/s -- -7% -37%
    post 10798/s 7% -- -32%
    range 15982/s 58% 48% --

    Rate post pre range
    post 10139/s -- -2% -35%
    pre 10370/s 2% -- -34%
    range 15678/s 55% 51% --

    Rate pre post range
    pre 10647/s -- -2% -34%
    post 10900/s 2% -- -33%
    range 16209/s 52% 49% --

    N => 10_000:

    Rate pre post range
    pre 990/s -- -10% -38%
    post 1099/s 11% -- -31%
    range 1597/s 61% 45% --

    Rate post pre range
    post 983/s -- -5% -39%
    pre 1037/s 5% -- -36%
    range 1621/s 65% 56% --

    Rate post pre range
    post 1013/s -- -3% -38%
    pre 1047/s 3% -- -36%
    range 1627/s 61% 55% --

    The difference between pre and post is generally small and sometimes pre
    is faster and sometimes post is faster. So the difference between them
    is probably less than the precision of the measurement.

    hp

    PS: On my system, for this simple loop, all three variants are the same
    speed for N in (14 .. 20). For lower values, range is consistently
    slower than pre or post, for larger values, it is consistently faster.
    If you have a different version of perl, a different processor, or a
    more complex loop, results may be different.

    PPS: N-1 is optimized by the compiler, so that doesn't make a
    difference.
     
    Peter J. Holzer, Nov 23, 2008
    #6
  7. Peng Yu

    News123 Guest

    Hi Peter,

    Is this a copy paste error?

    You seem to test twice the pre-increment:

    > {
    > 'pre' => sub { for(my $i = 0; $i <N; ++ $i) {} },
    > 'post' => sub { for(my $i = 0; $i <N; ++ $i) {} },
    > 'range' => sub { for my $i (0 .. N-1) {} },




    I changed the script to make pre and psot different and to use N=100
    instead of N=10.

    Range is now sometimes faster then pre/post.
    Apart from this still quite random:

    $ perl bla.pl
    Rate pre range post
    pre 69139/s -- -14% -18%
    range 80766/s 17% -- -4%
    post 83995/s 21% 4% --
    $ perl bla.pl
    Rate post pre range
    post 59401/s -- -5% -33%
    pre 62784/s 6% -- -29%
    range 88636/s 49% 41% --
    $ perl bla.pl
    Rate pre post range
    pre 60821/s -- -1% -27%
    post 61321/s 1% -- -26%
    range 83067/s 37% 35% --
    $ perl bla.pl
    Rate pre post range
    pre 58606/s -- -2% -33%
    post 60009/s 2% -- -31%
    range 87417/s 49% 46% --


    bye


    N
    Peter J. Holzer wrote:
    > On 2008-11-21 05:32, Jürgen Exner <> wrote:
    >> Peng Yu <> wrote:
    >>> I learned in C++, that it is better to use pre increment rather than
    >>> post increment. I'm wondering which one is better to use in perl,

    >> It depends on what you want to do. In that expression, do you need the
    >> old value before the increment or the new value after the increment?

    >
    > In the example he gave, he needs neither the old nor the new value. He
    > just needs the side effect. This is very common in C and C++, and the
    > only case where you pre- and postincrement are semantically equivalent,
    > so you can choose one or the other.
    >
    > Pre-increment is semantically simpler. It increments the variable and
    > returns the new value. Post-increment needs to save the old value before
    > incrementing the variable, so that it can return the old value.
    >
    > For simple variables this doesn't make any difference in C++, since the
    > compiler can just optimize the copy away. But for objects, it's not so
    > simple (the copy itself may cause some side-effect) so the usual advice
    > is to use pre-increment if you don't need the return value.
    >
    > Perl has a very weak optimizer (because it needs to be fast), so
    > pre-increment might be faster.
    >
    >>> example, in a for loop.
    >>>
    >>> for(my $i = 0; $i <10; ++ $i)
    >>>
    >>> or
    >>>
    >>> for(my $i = 0; $i <10; $i ++)
    >>>
    >>> Which one is better?

    >
    > Why don't you just try it?
    >
    >> Neither, nor. The best is a very simple and much more readable
    >>
    >> for my $i (0..9)

    >
    > #!/usr/bin/perl
    > use warnings;
    > use strict;
    > use Benchmark qw(cmpthese);
    >
    > use constant N => 10;
    >
    > cmpthese (-5,
    > {
    > 'pre' => sub { for(my $i = 0; $i <N; ++ $i) {} },
    > 'post' => sub { for(my $i = 0; $i <N; ++ $i) {} },
    > 'range' => sub { for my $i (0 .. N-1) {} },
    > });
    > __END__
    >
    > Oops, the range is consistently the slowest:
    >
    > Rate range post pre
    > range 667769/s -- -7% -7%
    > post 714756/s 7% -- -1%
    > pre 721696/s 8% 1% --
    >
    > Rate range post pre
    > range 634634/s -- -8% -9%
    > post 691932/s 9% -- -0%
    > pre 694498/s 9% 0% --
    >
    > Rate range post pre
    > range 636271/s -- -14% -19%
    > post 739517/s 16% -- -6%
    > pre 786373/s 24% 6% --
    >
    > but let's try N => 100:
    >
    > Rate pre post range
    > pre 103353/s -- -0% -27%
    > post 103859/s 0% -- -27%
    > range 141336/s 37% 36% --
    >
    > Rate post pre range
    > post 91995/s -- -8% -34%
    > pre 100124/s 9% -- -28%
    > range 140021/s 52% 40% --
    >
    > Rate post pre range
    > post 96837/s -- -7% -31%
    > pre 103855/s 7% -- -26%
    > range 140913/s 46% 36% --
    >
    > Now, using a range is the fastest version, and that advantage increases for larger loops:
    >
    > N => 1000:
    >
    > Rate pre post range
    > pre 10094/s -- -7% -37%
    > post 10798/s 7% -- -32%
    > range 15982/s 58% 48% --
    >
    > Rate post pre range
    > post 10139/s -- -2% -35%
    > pre 10370/s 2% -- -34%
    > range 15678/s 55% 51% --
    >
    > Rate pre post range
    > pre 10647/s -- -2% -34%
    > post 10900/s 2% -- -33%
    > range 16209/s 52% 49% --
    >
    > N => 10_000:
    >
    > Rate pre post range
    > pre 990/s -- -10% -38%
    > post 1099/s 11% -- -31%
    > range 1597/s 61% 45% --
    >
    > Rate post pre range
    > post 983/s -- -5% -39%
    > pre 1037/s 5% -- -36%
    > range 1621/s 65% 56% --
    >
    > Rate post pre range
    > post 1013/s -- -3% -38%
    > pre 1047/s 3% -- -36%
    > range 1627/s 61% 55% --
    >
    > The difference between pre and post is generally small and sometimes pre
    > is faster and sometimes post is faster. So the difference between them
    > is probably less than the precision of the measurement.
    >
    > hp
    >
    > PS: On my system, for this simple loop, all three variants are the same
    > speed for N in (14 .. 20). For lower values, range is consistently
    > slower than pre or post, for larger values, it is consistently faster.
    > If you have a different version of perl, a different processor, or a
    > more complex loop, results may be different.
    >
    > PPS: N-1 is optimized by the compiler, so that doesn't make a
    > difference.
     
    News123, Nov 23, 2008
    #7
  8. On 2008-11-23 14:05, News123 <> wrote:
    > Hi Peter,
    >
    > Is this a copy paste error?


    Yes. But unfortunately it is a copy & paste error I made in the test
    script, and not just in the posting, so pre and post
    being roughly the same speed was to be expected.

    > You seem to test twice the pre-increment:
    >
    >> {
    >> 'pre' => sub { for(my $i = 0; $i <N; ++ $i) {} },
    >> 'post' => sub { for(my $i = 0; $i <N; ++ $i) {} },
    >> 'range' => sub { for my $i (0 .. N-1) {} },

    >


    However, if I fix it:

    'pre' => sub { for(my $i = 0; $i <N; ++ $i) {} },
    'post' => sub { for(my $i = 0; $i <N; $i++) {} },
    'range' => sub { for my $i (0 .. N-1) {} },

    and then run it through -MO=Deparse, the result shows that the optimizer
    simplifies $i++ to ++$i:

    use Benchmark (':hireswallclock', 'cmpthese');
    use constant ('N', 14);
    use warnings;
    use strict 'refs';
    cmpthese(-2, {'pre', sub {
    for (my $i = 0; $i < 14; ++$i) {
    ();
    }
    }
    , 'post', sub {
    for (my $i = 0; $i < 14; ++$i) {
    ();
    }
    }
    , 'range', sub {
    foreach my $i (0 .. 13) {
    ();
    }
    }
    });
    foo syntax OK

    So, since both generate the same code, they should still be the same speed ;-).

    hp
     
    Peter J. Holzer, Nov 23, 2008
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. eddiew_AUS
    Replies:
    18
    Views:
    643
    Andrey Tarasevich
    Jan 27, 2004
  2. Andreas Sheriff
    Replies:
    10
    Views:
    726
    Jack Klein
    Sep 25, 2004
  3. kailasam

    Post and pre increment

    kailasam, Jun 14, 2004, in forum: C Programming
    Replies:
    14
    Views:
    21,154
    zainlucky
    Dec 5, 2008
  4. Replies:
    10
    Views:
    45,056
    gene tani
    Jan 13, 2006
  5. Alf P. Steinbach /Usenet
    Replies:
    0
    Views:
    900
    Alf P. Steinbach /Usenet
    May 22, 2011
Loading...

Share This Page