Hello!
I have a few questions about efficient code as I need to try and squeeze some more performance out of an arduino Mega.
Which is more efficient / quicker to run? Im not really concerned about memory usages as if still got plenty free (>1000)
::::::EXAMPLE A:::::::
time t = now();
if((hour(t)==12)&&(minutes(t)==10)&&(seconds(t)==30)||(hour(t)==10)&&(minutes(t)==15)&&(seconds(t)==35)){
doFunctionA();
}
::::::EXAMPLE B:::::::
time t = now();
if((hour(t)==12)&&(minutes(t)==10)&&(seconds(t)==30)){
doFunctionA();
}
else if ((hour(t)==10)&&(minutes(t)==15)&&(seconds(t)==35)){
doFunctionA();
}
And which one would be more efficient / quicker to run out of these?
:::::::EXAMPLE A:::::::
if((EEPROM.read(3000)==1)||(EEPROM.read(3001)==1)) {
doFunctionsA();
}
:::::::EXAMPLE B:::::::
byte a = EEPROM.read(3000));
byte b = EEPROM.read(3001));
if ((a==1)||(b==1)){
doFunctionsA();
}
You could use millis()... the blink without delay sketch is the other hint.. and get the answer from DofunctionA
Doc
In the first set, A & B probably compile to the same code. Did you try compiling them?
The compiler will rewrite your code to its most efficient form ( that it can devise ), which may render all your attempts at optimization equal and of no additional benefit.
B just seems intentionally wasteful as both if & else if call the same function. However it may be more readable to you.
The second set would be equal, and the second B also depends on weather a & b are used elsewhere. I would personally use A, there is no need to store the result as you already know it using the literal in the comparison.
As a professional programmer for 30 years, I had a standard response when a programmer asked me about performance differences in code like this. Even on slow, early IBM PC's, you could drag out an ellipse and rubber band its drawing on a graphical display. If you've ever done the math for calculating the pixels in an ellipse you quickly realize that even a slow PC can do an amazing amount of work in very short periods of time.
In your case, I think you'd be hard pressed to actually measure any difference. At worst, you're probably looking at a couple of instructions.
A bigger issue is readability and maintainability. In I code reviewed, I almost always red flagged code that mixed logic in a single if statement. This may sound like an extreme and unnecessary rule but in practice it keeps code very readable and minimizes the possibility of breaking it with future modifications. When you mix logic, you require the reader to do the logic operation in their head. If you actually structure the code to reflect the logic, it's much easier to follow and it's much safer when future changes are necessary.
An alternative approach is to do separate logic into temporary variables. For example,
boolean conditionA = a == 1 and b==3;
boolean conditionB = x == 3 and y == 5;
if (conditionA || condition B) {
...
With good choice of variable names and the separation of logic, you end up with code that is much more readable and robust.
The effect on speed was negligible but there was a huge gain in robustness of the code.
The difference in performance here would be negligible or more likely zero as already noted. Why are you looking at this particular piece of code to find improvements?
Without seeing the rest of your code, It's hard to tell of course, but I'd expect that there may be other areas that would have better opportunities for performance improvements. For example, do you have any calls to delay in your sketch?
In the first question, both examples are the same. If you used seconds since midnight instead of hours, minutes, seconds, worst case would be two comparisons instead of 4.
In the second question, example A will be faster when EEPROM.read(3000) equals 1, since this saves a EEPROM read. If you think location 3001 is more likely to equal 1 then reorder the comparisons.
See Short-circuit evaluation - Wikipedia
A bigger issue is readability and maintainability.
Bingo! Someone once said that writing code is 20% of its cost, while debugging and maintaining the code is the remaining 80%. When I had my own software company, I usually assigned the coding task to small teams of 2 or 3 programmers. The typical time frame would be one or two weeks for a task. Each Friday, all of the programmers (small company with a max of 9 coders) attended a code walkthrough. If the team passed the code walkthrough, everyone got free pizza for lunch and everyone could leave early that day. The point: 1) different sets of eyes on the code are a test of its readability, 2) everyone had a least some idea of what each team was doing and how the pieces-parts fit together, 3) if one person went on vacation, it was easier for someone else to fill in, and 4) it fostered a we're-all-in-this-boat-together understanding. You'd be amazed how many times the programmers external the team were there long after closing on Thursday, just so they could get a free pizza and a few hours off. I think the result was more than worth the cost and it did produce better and more easily maintained code.