Optimizing Loops

Last modified by Microchip on 2024/01/22 23:05

Loops are used regularly throughout source code. The loop constructs themselves are often considered extraneous to the loop body that performs the main task at hand, but all parts of a loop can affect the speed at which it executes.

There are several things you can look at to improve loop execution speed. When considering the overall execution time of your program, any speed improvement you can make in the loop code is multiplied by the number of iterations the loop performs. Even small improvements in a loop can make a big difference overall if the loop iterates a large number of times.

The loop index variable can be accessed many times during each iteration of the loop. Consider the following code snippet that contains typical loop code, where N is defined as an arbitrary value.

1
2
for(i=0; i<N; i++)
    array[i] = 0x55;

In this example, the index, i, is accessed three times per iteration even though this is a simple loop example. It is important to ensure that the loop index variable has a type that can be efficiently accessed. See the "Choosing an Integer Data Type" page, which explains the fastest minimum-width integer types provided by the compiler. Alternatively, for MPLAB® XC16 and XC32, use an int type and for MPLAB XC8, use a char type if the number of iterations, N, can be held by these types. Choose an unsigned type if possible, as this might lead to even faster execution.

Let's rewrite the previous example loop using a different controlling expression.

1
2
for(i=0; i!=N; i++)
    array[i] = 0x55;

Here we use a strong relational operator (!=) in the controlling expression, i, not equal to N. This expression is checking for one single value; i is either equal to N or it is not. Although the weaker less-than operator (<) is commonly used by programmers, the strong operator can often produce smaller, faster code. This is because it is typically easier for code to check for a single value than for a range of values.

For some device instruction sets, counting down in the loop can lead to faster execution. If you do count down, check all the expressions in the loop that use the loop index. Ensure they are appropriate for the new range of values the loop index covers, especially the last value. In the next example, the loop will terminate as soon as the loop index reaches 0. The array index expression in the body of the loop has been adjusted accordingly.

1
2
for(i=N; i!=0 ; i--)
    array[i-1] = 0x55;

Look for other optimizations that might speed execution. For example, in instances where an expression is being evaluated multiple times, each iteration can be factored out, evaluated just once, and stored for reuse. But before optimizing loop code—indeed any code—it is worth checking first that the compiler you are using is not already performing these optimizations for you. Above all, make sure your source code is easily readable and clearly indicates the operation you intend.