In a DO loop of the form
do jx = 1 to 12;
...
end;
The variable "jx" is known as the DO loop control variable.
The performance of the loop will vary greater depending on how you declare it and how you use it:
Declaring loop control variables
1. The performance will be best if you declare a loop control variable as AUTOMATIC and much worse if you declare it as BASED or CONTROLLED (or if is a PARAMETER). The 6.1 compiler will flag these poor choices with a warning message.
2. The performance will also be much better if you declare the control variable as FIXED BINARY rather than as FIXED DECIMAL, PICTURE, or FLOAT(!?). You should declare the control variable as FIXED BIN(31) unless it will be an index into a very large array (and then you should declare it as FIXED BIN(63)). With the 6.1 compiler, you can simplify this by using the predefined alias __signed_int and declaring these do loop control variables as type __signed_int; for example:
declare jx type __signed_int;
The 6.1 compiler will also flag these poor choices with a warning message.
3. Finally, you should declare the control variable in the same PROCEDURE or BEGIN as where it is used. Never declare it in a parent block (and not only is that bad for performance, it is also poor software engineering and makes your code less transparent and less easy to understand).
The Enterprise PL/I compiler has had, for many years, the option RULES(NOGLOBALDO) which flags code that does not follow this guideline. If you care about the performance of your code, you should specify this option, and it is likely to become the default in a future release.
Using loop control variables
The compiler will generate better code for a loop with a control variable if the compiler can easily see if the control variable is changed (and the compiler can do the best job optimizing a loop if it can clearly see that the DO loop control variable is changed only by the DO loop statement itself).
To make that more likely, it is best to follow these rules:
- Do not use a loop control variable in a child block, and do not pass it BYADDR to any routine (since the compiler will have to assume that the variable is changed by that routine).
- Do not assign its address to a pointer.
- If possible, do not change it inside the loop.