This document covers the following topics:
Best performance is achieved when you use the data formats packed numeric (P) and integer (I4) in arithmetic operations.
Avoid converting data between the formats packed numeric (P), unpacked numeric (N), integer (I), and floating point (F), as this causes processing overhead even with optimized code.
As there is no interpretation overhead with optimized code, the differences between the various data formats become much more prominent: with optimized code the performance improvement gained by using format P instead of N, for example, is even higher than with normal code.
A = A + 1
In the above numeric calculation
with non-optimized code, format P executes approximately 13 % faster than format N.
with optimized code, however, format P executes approximately 56 % faster than format N.
The performance gain which would be achieved by applying the Natural Optimizer Compiler to this simple statement is
with unpacked operands (N): 8 times faster
with packed operands (P): 15 times faster
Array range operations, such as
MOVE A(*) TO B(*)
are executed more efficiently than if the same function were programmed
using a FOR
statement processing loop. This is also true for
optimized code.
When indexes are used, integer format I4 should be used to achieve optimum performance.
We recommend that you adjust the length of the alphanumeric constant to the length of the variable, when moving an alphanumeric constant to an alphanumeric variable (format A), or when comparing an alphanumeric variable with an alphanumeric constant. This will significantly speed up operation, for example:
A(A5):='XYZAB' ... IF A = 'ABC ' THEN ...
is faster than
IF A = 'ABC' THEN ...
When using the DECIDE ON
statement with a system variable,
array or parameter operand1
, it is more
efficient to move the value to a scalar variable of the same type and length
defined in the LOCAL
storage section.
When using numeric constants in assignments or arithmetic operations, try to force the constants to have the same type as the operation.
Any numeric constant with or without a decimal but without an exponent is compiled to a packed number having the minimum length and precision to represent the value, unless the constant is an array index or substring starting position or length, in which case it becomes a four-byte integer (I4). This rule applies irrespective of the variable types participating in the operation.
Operations containing floating point will be executed in floating
point. Add E00
to numeric values to force them to be floating
point, for example:
ADD 1E00 to F(F8)
Operations not containing floating point, but containing packed
numeric, unpacked numeric, date or time variables will be executed in packed
decimal. For ADD
, SUBTRACT
and IF
, force
numeric constants to have the same number of decimal places as the variable
with the highest precision by adding a decimal place and trailing zeros, for
example:
ADD 1.00 TO P(P7.2)
This technique is unnecessary for MULTIPLY
and
DIVIDE
.
To ease the optimization process, try to keep all scalar references at the front of the data section and all array references at the end of the data section.
The Natural Optimizer Compiler contains an algorithm to enhance the performance even further. In terms of performance, a statement will differ depending on the types of operands. The statement will execute more slowly if one or more of the operands is a parameter, array or scalar field of Type N (numeric) or combinations of these operands. The NOC analyzes the program flow and determines which variables with one or more of these characteristics are read two or more times without being written to. It then moves the value of each variable to a temporary cache area where it can be accessed quickly under the following conditions:
The variable is accessed often but seldom modified and
The variable is an array of any type or a scalar field of Type N (numeric).
Most suitable for variable caching are programs with long sequences that repeatedly access the same variable, in particular if the variable is an array. Variable caching then avoids complex and recurring address computation.
The example program displayed below demonstrates the advantage of
variable caching. Cataloged with NODBG
(see below) and
CACHE=ON
, executing this program in a test environment took 47 %
of the time required to execute the program with NODBG
and
CACHE=OFF
. Cataloging the program with CACHE=ON
,
reduces the code generated by the NOC from 856 bytes to 376 bytes.
DEFINE DATA LOCAL 1 ARR(N2/10,10,10) 1 I(I4) INIT <5> 1 J(I4) INIT <6> 1 K(I4) INIT <7> END-DEFINE DECIDE ON EVERY ARR(I,J,K) VALUE 10 IGNORE VALUE 20 IGNORE VALUE 30 IGNORE VALUE 40 IGNORE VALUE 50 IGNORE VALUE 60 IGNORE VALUE 70 IGNORE VALUE 80 IGNORE VALUE 90 IGNORE NONE IGNORE END-DECIDE
Warning: If the content of a cached variable is modified with the command MODIFY VARIABLE of the
Natural Debugger, only
the content of the original variable is modified. The cached value (which may
still be used in subsequent statements) remains unchanged. Therefore, variable
caching should be used with great care if the Natural Debugger is used. See
also the Natural Debugger documentation. |
Once a program has been thoroughly tested and put into production, you should catalog the program with the NODBG option as described in the section Optimizer Options. Without debug code, the optimized statements will execute from 10% to 30% faster.
The code to facilitate debugging is removed when this option is
specified, even with INDX
or OVFLW
options turned
on.