++u or u++ which is faster?

T

The Doctor

Hi all,

Recently I was asked the question about whether ++U or U++ is
faster if U is a user defined type. What's the answer?

Thank you
 
V

Vaclav Haisman

Usually operator ++ (int) is implemented like this:

T operator ++ (int)
{
T tmp = *this;
++*this;
return tmp;
}

If compiler isn't able to optimize away the initialization of the temporary
then using u++ is slower. That's why it is usually better to use
pre-increment/pre-decrement instead of post-decrement/post-increment.

VH
 
J

JKop

The Doctor posted:
Hi all,

Recently I was asked the question about whether ++U or U++ is
faster if U is a user defined type. What's the answer?

Thank you


++u is faster.


Always use ++u. Never use u++ unless you need to.


-JKop
 
M

Method Man

The Doctor said:
Hi all,

Recently I was asked the question about whether ++U or U++ is
faster if U is a user defined type. What's the answer?

Thank you

The simple answer is when using U++, the object U needs to get copied twice
whereas with ++U, it need only be copied once.

So use ++U unless you specifically require the value of the post-increment.
 
C

Chris Theis

JKop said:
The Doctor posted:



++u is faster.

This general statement is not true. It depends on the datatype and the
optimization of the compiler. Both types might be the same speed, but as you
say it's generally wise to use ++u.
 
S

Simon Stienen

Ioannis Vranos said:
For built-in types their speed is the same. For user defined types it
applies what you say.

So lets state:
++u is never slower.

Now it's perfect ;P
 
R

Rolf Magnus

Method said:
The simple answer is when using U++, the object U needs to get copied
twice whereas with ++U, it need only be copied once.

What would that extra copy be needed for? I can see U++ doing at most 2
copies (but usually one - or if the function gets inlined and the return
value is not used even both - of them getting optimized away) and ++U doing
none at all. Consider the operators for an iterator into a linked list:

class mylistiterator
{
public:
//...

mylistiterator& operator++()
{
node = node->next;
return *this;
} // no copy made

mylistiterator operator++(int)
{
myiterator ret = *this; // first copy
node = node->next;
return ret; // second one, usually optimized away
}
private:
mylist::node* node;
};

So it stands 0 to 2 copies for postfix++ vs. 0 for prefix++.
 
M

Method Man

The simple answer is when using U++, the object U needs to get copied
What would that extra copy be needed for? I can see U++ doing at most 2
copies (but usually one - or if the function gets inlined and the return
value is not used even both - of them getting optimized away)

One time to store the old value, and another time for returning the old
value. Of course any optimizations are compiler-specific, dependent on
things like inlining, register variables, etc, or dependent on the
++operator code if U is a user type.

But I was speaking theoretically.
and ++U doing
none at all.
...

You're probably right here.

I guess the bottom line is U++ is never faster than ++U.
 
J

JKop

Simon Stienen posted:
So lets state:
++u is never slower.

Now it's perfect ;P

Unless ofcourse I play Devil's Advocate and write my own unique ++u
operator!

-JKop
 
P

Pedro Miguel Carvalho

| Hi all,
|
| Recently I was asked the question about whether ++U or U++ is
| faster if U is a user defined type. What's the answer?
|
| Thank you

The answer is that it depends on those two operator in the user defined
type. ++U is usually faster.

Does any one know why these two operator are not symmetrical?

UserType& operator++ ( ); // prefix ++
UserType operator++ (int dummy); // postfix ++

Why can't it be:

UserType& operator++ (int dummy); // postfix ++

What is the rational behind this?

Thanks,
Pedro Carvalho
 
J

JKop

Does any one know why these two operator are not symmetrical?
UserType& operator++ ( ); // prefix ++
UserType operator++ (int dummy); // postfix ++

Why can't it be:

UserType& operator++ (int dummy); // postfix ++

What is the rational behind this?

Thanks,
Pedro Carvalho


int& Blah()
{
int k = 7;

return k;
}


If you don't see the problem in the above then I'd be surprised that you
know about operator overloading in the first place. (Not an insult, just an
observation.)

But ofcourse, you can always:


int& Blah()
{
return *new int(7);
}



just as long as you call delete down the road...


-JKop



-JKop
 
D

David Hilsee

Pedro Miguel Carvalho said:
| Hi all,
|
| Recently I was asked the question about whether ++U or U++ is
| faster if U is a user defined type. What's the answer?
|
| Thank you

The answer is that it depends on those two operator in the user defined
type. ++U is usually faster.

Does any one know why these two operator are not symmetrical?

UserType& operator++ ( ); // prefix ++
UserType operator++ (int dummy); // postfix ++

Why can't it be:

UserType& operator++ (int dummy); // postfix ++

What is the rational behind this?

++foo should increment foo and return foo. On the other hand, foo++ should
increment foo and return the value it had before it was incremented. It
should not return a reference to itself, because that would be confusing.
It should not return a reference to another instance of UserType because it
causes the problems described in JKop's post. It simply can't return a
reference without causing complications.
 
A

assaarpa

For built-in types their speed is the same. For user defined types it
applies what you say.

Not necessarily, the architechture could be register starved and ++u might
fit the computation in the ALU registers while ++u might not, on the other
hand this might not have any real-world impact on the performance as the ISA
might be translated dynamically to format the hardware ALU uses internally,
which may result in same transistors having the same inputs in the same
sequence. IA32 is a prime example of architechture where this evaluation has
a good chance of being realized.

Some architechtures even make distinction of post- and pre-
increment/decrement in their binary instructions, think of Motorola 680x0 as
one example. It might make a difference or it might not, that depends on the
context. As far as the programming language c++ is concerned it does appear
to make a difference.
 
P

Pedro Miguel Carvalho

| | > | > Does any one know why these two operator are not symmetrical?
| >
| > UserType& operator++ ( ); // prefix ++
| > UserType operator++ (int dummy); // postfix ++
| >
| > Why can't it be:
| >
| > UserType& operator++ (int dummy); // postfix ++
| >
| > What is the rational behind this?
|
| ++foo should increment foo and return foo. On the other hand, foo++
should
| increment foo and return the value it had before it was incremented. It
| should not return a reference to itself, because that would be confusing.
| It should not return a reference to another instance of UserType because
it
| causes the problems described in JKop's post. It simply can't return a
| reference without causing complications.

I understand why foo++ must return a copy of the old value if it is executed
at the beginning of the statement.
For example
bar( ++I );
is equivalent to
++I;
bar( I );
and
bar( I++ );
is equivalent to (J is temporary)
J = I++;
bar( J );
My question is why not evaluate I++ after bar() like this
Make
bar( I++ );
equivalent to
bar( I );
I++;

Of course, all this was decided long ago and nothing will be changed now.

Pedro Carvalho
 
A

assaarpa

Why can't it be:

It can be.
What is the rational behind this?

More often than not the other form yields predictable results which is quite
important rational in general.
 
F

Filipe Valepereiro

Always use ++u, since they're suposed to be faster.
If you use iterator's then you must allways use ++u.
this is a recommendation from Bjarne Stroustrup book,
see chapter about Iterators
 
T

Thomas Matthews

Method said:
The simple answer is when using U++, the object U needs to get copied twice
whereas with ++U, it need only be copied once.

So use ++U unless you specifically require the value of the post-increment.

Depends on the compiler's optimizer and how the increment is
used.

For example:
/* 1 */ int i = 6;
/* 2 */ ++i;
/* 3 */ i++;

In the above example, the compiler can translate lines
2 and 3 into simple increment instructions that have no
copy requirements.


--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book
 
T

Thomas Matthews

The said:
Hi all,

Recently I was asked the question about whether ++U or U++ is
faster if U is a user defined type. What's the answer?

Thank you

According to the "Effective C++" and "More Effective C++"
books by Scott Meyers, the prefix form (++U) should be
preferred over the postfix version.

As far as speed is concerned, the difference is negligble
depending on how large the type is for U; or how complex
an increment operation is. One should alway profile
the _whole_ program before worrying about efficiency
of one expression or statement.

Profile your own code. If the section that _needs_
optimizing contains the increment operator, have the
compiler print out an assembly language listing of
that section. See how the compiler is translating
the increment. If _you_ can optimize that one statement
better in assembly, then reorganize the source to
provide hints to the compiler. I really doubt that
a person can optimize only the incrementing in assembly
due to the overhead involve in a call to an assembly
language function. A person may be able to optimize
better than the compiler by using inline assembly,
but by this time, you are wasting more time playing
with the compiler than producing code and finishing
the project.

Just pick a preference and stick to it. Worry about
the efficiency after the program works correctly
and is robust. If there is a _need_ for space or
time for optimization, then perform it at the end.
Sometimes, when the program is running extremely
slow or is extremely huge during development, some
optimizations may be necessary. For example, if
an embedded system runs out of execution space
before the integration phase is completed, optimizations
should be performed (such as removing unnecessary
code). But, in general, save optimizations for
after the progam is finished.

Spend your time on a more worthwhile endeavor,
such as making the code more readable.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
474,176
Messages
2,570,947
Members
47,501
Latest member
Ledmyplace

Latest Threads

Top