I don't think the compiler is allowed to swap the conditions, because if flag == true in the second case, millis should not be called (it could have side effects).
if (flag == false && millis() - lastMillis >= 500)
I would have thought that placing the 'flag test' at the front would have given a shorter time but it did not.
It depends. If the "flag test" evaluates to TRUE, then the code has to do both tests regardless, so the timing should be the same. If the first test evaluates to FALSE, the second test doesn't need to be evaluated. So having the boolean check first only speeds things up when the result is FALSE.
In your "full example", flag is a compile-time constant, so it's check is entirely eliminated from the executable code, and the if clauses are empty, so most of the conditional code is removed as well, leaving only the reads/writes of volatiles that are forced upon the compiler...
You really can't analyze code execution to this degree without looking at the asm...
All you get is:
They two sequences the same on my scope - about 750ns between blips (~11 cycles for reading timer0_millis - seems about right.)
(Since this doesn't agree with what you were seeing, perhaps... it's not quite the same code?)
if (millis() - lastMillis >= 500 && flag == false)
{
//this gave 1.25us
}
The body is empty, so the value of the condition becomes irrelevant and the comparisons are optimized away. The only thing that cannot be removed is calling millis().
Adding someting (like PINB = 0x10) to the body should make this test more meaninful.
westfw:
It depends. If the "flag test" evaluates to TRUE, then the code has to do both tests regardless, so the timing should be the same. If the first test evaluates to FALSE, the second test doesn't need to be evaluated. So having the boolean check first only speeds things up when the result is FALSE.
In your "full example", flag is a compile-time constant, so it's check is entirely eliminated from the executable code, and the if clauses are empty, so most of the conditional code is removed as well, leaving only the reads/writes of volatiles that are forced upon the compiler...
. . .
They two sequences the same on my scope - about 750ns between blips (~11 cycles for reading timer0_millis - seems about right.)
(Since this doesn't agree with what you were seeing, perhaps... it's not quite the same code?)
Once again you have restored my faith!
~800ns less if I use true and move the Flag test to the front.
The compiler is smart enough to notice that 'flag' is initialized and never modified so it can be treated as a constant. One way to avoid having the compiler optimize away code that you want to time is to declare variables 'volatile'.