Ask Reuben

Options Short Circuit

How can I make my program faster?

How can I reduce complexity of code?

If you are trying to improve the performance of a program you can use the profiler to measure what percentage of time the program spends in a function and code coverage to measure how many times a line is executed.  (I should do an ask-reuben on these tools one day).

These can normally point you at areas such as CONNECT which can take some time to execute, and can also point out that in cases such as …

FOR i = 1 TO foo()

… foo() is executed on each iteration of the loop and sometimes it is smarter to code …

DEFINE l_foo INTEGER

LET l_foo = foo()
FOR i = 1 TO l_foo

… if the value of foo() does not change as the result of the processing of the loop.  The other tip here is to code …

FOR i = foo() TO 1 STEP -1

… if the order in which the loop is evaluated does not matter.  In both cases, foo() is only evaluated once rather than being evaluated on each iteration of the loop, potentially unnecessarily if the value is not expected to change.

This brings me onto other areas where functions are evaluated potentially unnecessarily.  Consider …

IF a() AND b() THEN

… if a() returns FALSE, is it necessary to evaluate b()?  The answer is no as it won’t change the result of the IF.  Similarly …

IF a() OR b() THEN

… if a() returns TRUE, it is equally not necessary to evaluate b() as the result of the IF won’t change.

However by default Genero (as Informix-4gl did before it) will perform these potentially unnecessary evaluations that don’t change the result of the IF.

Also if you nest the IF statements e.g.

IF a() THEN
    IF b() THEN
        -- handle success
    ELSE
        -- handle failure
    END OF
ELSE
    -- handle failure
END IF

… then you have the complexity of how to handle the failure case when …

IF a() AND b() THEN
    -- handle success
ELSE
    -- handle failure
END IF

… is neater.

This leads to OPTIONS SHORT CIRCUIT which can be used to control the semantics of the AND and OR operators.

By including the OPTIONS SHORT CIRCUIT instruction at the beginning of the module, it will instruct the compiler to optimize the behaviour  by using the short-circuit or minimal evaluation method.

It also has a benefit in that it allows as illustrated in one of the above links, code of this nature …

IF x <= arr.getLength() AND foo(arr[x].*) THEN

With OPTIONS SHORT CIRCUIT you can be assured that x is valid for the length of the array and won't create additional array elements.  Without OPTIONS SHORT CIRCUIT, the right hand side will be evaluated and if arr is a DYNAMIC ARRAY and x > arr.getLength(), the extra array elements would be automatically created which in most cases is not what the developer intended to happen.

To finish, I used the word potentially a lot above because there maybe some code inside the function you do want evaluated.  So it is important that when considering wether to use OPTIONS SHORT CIRCUIT that you review your code and ensure that the functions that won't be evaluated are not expected to have done something as well as returning TRUE or FALSE.