Boolean Comparison Efficiency? In C

I am writing a loop in C, and I'm just wondering how to optimize it a bit. This is not important here, as I am just practicing, but for further knowledge I would like to know:

In a loop, for example, the following snippet:

int i = 0; while (i < 10) { printf("%d\n", i); i++; } 

Does the processor check both (i < 10) and (i == 10) for each iteration? Or is it simple to check (i < 10) and, if true, continue?

If he checks both, will not:

 int i = 0; while (i != 10) { printf("%d\n", i); i++; } 

be more effective?

Thanks!

+4
source share
9 answers

Both will be translated into one assembly instruction. Most processors have comparison instructions for LESS, FOR LESS OR EQUAL, for EQUAL, and NOT EQUAL.

+10
source

One of the interesting things about these optimization issues is that they often show why you should code for clarity / correctness before worrying about the performance impact of these operations (which often do not make any difference).

Your 2 cycle loops do not have the same behavior:

 int i = 0; /* this will print 11 lines (0..10) */ while (i <= 10) { printf("%d\n", i); i++; } 

and

 int i = 0; /* This will print 10 lines (0..9) */ while (i != 10) { printf("%d\n", i); i++; } 

However, to answer your question, he is almost sure that the performance of the two constructions will be the same (it is assumed that you fixed the problem, so the number of cycles was the same). For example, if your processor could only check for equality and whether one value was less than the other in two separate steps (which would be a very unusual processor), then the compiler will most likely convert the test (i <= 10) to a tag (i < 11) or, possibly, a test (i != 11) .

+5
source

This is a vivid example of early optimization .... IMHO, this is what programmers new to their craft tend to worry about. If you need to worry about this, learn to compare and project your code so that your concerns are based more on evidence than on assumptions.

Talk with your specific questions. First, <= not implemented as two testing operations for < and == separately in any C compiler I have encountered in my career. And that includes some monumental silly compilers. Note that for integers a <= 5 is the same condition as a < 6 , and if the target architecture only needs to use < , the code generator will do this.

Your second concern that while (i != 10) can be more efficient is causing an interesting defensive programming problem. First, there is no effectiveness in any reasonable target architecture. However, this increases the likelihood of a small error causing a larger glitch. Consider this: if some line of code inside the loop body is changed i , say, making it more than 10, what could happen? How long will it take to complete the cycle and will there be any other consequences of the error?

Finally, when you wonder about this, it is often worth figuring out what code your compiler uses. Most compilers provide a mechanism for this. For GCC, learn about the -S option, which will cause it to generate assembly code directly instead of creating an object file.

+3
source

The operators <= and <are a single instruction in the assembly; there should be no difference in performance. Note that tests for 0 may be slightly faster on some processors than checking for any other constant, so it might be wise to loop backward:

 int i = 10; while (i != 0) { printf("%d\n", i); i--; } 

Please note that micro-installations such as these can usually give you only very great performance, it is better to use your time to use efficient algorithms.

0
source

Depends on architecture and compiler. On most architectures, there is one command for <= or vice versa, which can be canceled, so if it is looped, the comparison is likely to be only one instruction. (On x86 or x86_64 this is one instruction)

The compiler can expand the loop into a sequence of ten times i++ , when only constant expressions are involved, it even optimizes ++ and leaves only constants.

And Ira is right, the comparison disappears if printf involved, the execution time of which can be millions of clock cycles.

0
source

Does the processor check both (i <10) and (i == 10) for each iteration? Or does he just check (i <10) and, if true, continue?

Neither one nor the other is likely to check (i <11). <= 10 just designed to help you better understand your code, since 11 is a magic number , which actually means (10+1) .

0
source
 // Case I int i = 0; while (i < 10) { printf("%d\n", i); i++; printf("%d\n", i); i++; } // Case II int i = 0; while (i < 10) { printf("%d\n", i); i++; } 

The code I of the code takes up more space, but quickly, and the Case II code takes up less space, but is compared more slowly with the Case I code. Because in programming, the complexity of space and time complexity are always proportional to each other. This means that you must compromise either space or time.
This way you can optimize the complexity of time or the complexity of space, but not both.

And your both codes are the same.

0
source

I am writing a loop in C, and I'm just wondering how to optimize it a bit.

If you compile with optimizations enabled, the biggest optimization will be to deploy this loop.

It will be difficult to profile this code with -O2, because for trivial functions, the compiler loops around and you cannot compare the actual differences in comparison. You should be careful when profiling test cases that use constants that can make the code trivial when optimized by the compiler.

0
source

disassembly. Depending on the processor, as well as optimization and a number of things, this simple code example really deploys or does things that don't reflect your real question. Compiling with gcc-O1, although both of the examples you provided led to the same assembler (for the hand).

Smaller than in your C code often turns into a branch if it is greater than or equal to the far side of the loop. If your processor does not have more or equal, it can have a branch, if it is more, and the branch is equal, two instructions.

usually though there will be a register containing i. there will be instructions for increasing i. Then the instruction to compare I with 10, and then equal, greater or equal and less than usual, is executed in one command, so you should not usually see the difference.

0
source

All Articles