开发者

Which method of incrementing is superior in C++?

开发者 https://www.devze.com 2022-12-10 02:53 出处:网络
I saw someone use this method to increment a variable: r = (r + 1) & 0xf; Is开发者_如何学C that method better/faster than just using:

I saw someone use this method to increment a variable:

r = (r + 1) & 0xf;

Is开发者_如何学C that method better/faster than just using:

r++;

Why would someone use a bitwise and, with 0xf, if it just duplicates?


Those are not the same. The first one increments r then performs a modulo operation on it, effectively doing the same thing as:

r = (r + 1) % 16;


The expression:

r = (r + 1) & 0xf;

Is actually equivalent to this (assuming r is guaranteed to be non-negative):

r = (r + 1) % 16;

Because of this, it's impossible to compare either of the statements above with r++. It doesn't matter which is "faster" or "better" because they don't do the same thing in the first place.


As others have stated, the two code snippets you posted are not equivalent. Updating the question based on that information the question becomes,

   Is r = (r + 1) & 0xf; better than r = (r + 1) % 16;?

Though one may come up with a situation in which the former notation is more applicable, I would say that in general no, it is not. The modulo operator makes it much clearer what is happening, and I imagine that most compilers will perform this optimization for you. Do not unnecessarily sacrifice readability for speed. (Of course, if you want to be sure about any possible speed difference, just compile both snippets to assembler, e.g. with gcc -S, and compare the output.)

Edit: nobar's remark below shows that things are usually not as straightforward as they appear. Unlike &, % is an arithmetic operator, and it is as such bound to some addtional rules (e.g. to ensure that negative arguments are properly handled). The two statements above are only equivalent for non-negative values or r. To ensure that the compiler can make such an assumption about r, it is best to declare it unsigned.


Those lines aren't equivalent. The first one will go back to zero if r is 15 before the call.


r++ should never be used to increment unless you need the pre-incremented value as an rvalue. Most compilers will optimize it to ++r if the post-increment functionality isn't needed, but its best not to rely on it. But you probably meant to ask for a comparison between ++r and (r + 1) & 0xf;, then I would submit that any fractional improvement that the latter might have one some particular compiler or hardware is insignificant compared to the greater difficulty in understanding and maintaining the code.

In general, avoid trying to be overly clever in optimizations that might not apply to another architecture.


There's no equivalence in the two code examples you give.
1) Is a fast way of limiting the value from 0 to 15 and doing a wrap-around to zero once the value exceeds 15.
2) Just increments a value with no upper limit ( apart from the inherent limit imposed by the size of the type that r is declared with i.e it would wrap > 255 if r were declared as unsigned char etc )

1) is an equivalent to doing this

if (r + 1 > 15 )
{
   r = 0;
}

So it may be more optimal on certain types of hardware because it eliminates the need for a branch etc


Comparing
r=(r+1) & 0xf;
and
++r;
r %= 0x10;

With any kind of compiler optimization when r is an integer they should be the same.


Perhaps you should ask yourself which method is clear and easy to understand for a programmer maintaining your code... C and C++ give a lot of syntax to say the same things and compilers are smarter than programmers in most situations, so the responsibility is to make code easy to understand.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号