post increment or pre increment?

P

Peng Yu

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
 
S

sln

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
 
J

Jürgen Exner

Peng Yu said:
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
 
P

Peter Makholm

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
 
T

Tim Greer

Peng said:
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.
 
P

Peter J. Holzer

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.

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.
 
N

News123

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
 
P

Peter J. Holzer

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:

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top