"if-else" and "switch-case" are widely used in C code, a proper organization of the branches can reduce the execution time.
For "if-else", always put the most probable conditions in the first place. Then the following conditions are less likely to be executed. Thus time is saved for most cases.
Using "switch-case" may eliminate the drawbacks of "if-else", because for a "switch-case", the compiler usually generates lookup tables with index and jump to the correct place directly.
If it's hard to use "switch-case", we can divide the "if-else" branches into smaller sub-branches. This method reduces the execution time for a worst case condition. In the table below, we get data from ADC and then send data through USART. "ad_result <= 240" is the worst case.
If-Else branch | If-Else sub-branch | |
---|---|---|
C source code |
#include <avr/io.h> uint8_t ad_result; uint8_t readADC() { return ADCH; }; void send(uint8_t data){ UDR0 = data; }; int main(void) uint8_t output; ad_result = readADC(); if(ad_result <= 30){ output = 0x6C; }else if(ad_result <= 60){ output = 0x6E; }else if(ad_result <= 90){ output = 0x68; }else if(ad_result <= 120){ output = 0x4C; }else if(ad_result <= 150){ output = 0x4E; }else if(ad_result <= 180){ output = 0x48; }else if(ad_result <= 210){ output = 0x57; }else if(ad_result <= 240){ output = 0x45; } send(output); } |
int main(void) { uint8_t output; ad_result = readADC(); if (ad_result <= 120){ if (ad_result <= 60){ if (ad_result <= 30){ output = 0x6C; } else{ output = 0x6E; } } else{ if (ad_result <= 90){ output = 0x68; } else{ output = 0x4C; } } } else{ if (ad_result <= 180){ if (ad_result <= 150){ output = 0x4E; } else{ output = 0x48; } } else{ if (ad_result <= 210){ output = 0x57; } else{ output = 0x45; } } } send(output); } |
AVR Memory Usage |
Program: 198 bytes (2.4% Full) (.text + .data + .bootloader) Data: 1 bytes (0.1% Full) (.data + .bss + .noinit) |
Program: 226 bytes (2.8% Full) (.text + .data + .bootloader) Data: 1 bytes (0.1% Full) (.data + .bss + .noinit) |
Cycle counter | 58 (for worst case) | 48 (for worst case) |
Compiler optimization level | -O3 | -O3 |
We can see it requires less time to reach the branch in the worst case. We could also note that the code size is increased. Thus we should balance the result according to specific requirement on size or speed.