You might be wondering (in fact, you should be wondering) how to tell which of two constructs is faster in your situation or how to measure the performance of a part of your application. OpenEdge has a performance profiling tool (called Profiler) that can show you exactly how much of your processing time is going to what routines, but there is also a much simpler way to do a test of a specific part of your code: the ETIME function (for elapsed time). ETIME returns an integer value representing the number of milliseconds since the function was reset to zero. Because a millisecond is a substantial amount of time on a modern processor, you often have to repeat an action many times inside a loop to measure accurately just what its cost is.

To reset the counter that ETIME uses, you invoke the function with an argument value of yes or true. Otherwise, you invoke it with no argument and no parentheses. If you forget to reset it to zero before you start, ETIME returns some enormous integer representing the number of milliseconds since your session started.

This example shows you whether it is faster to use the FIND statement or a FOR FIRST block to find the Order with a Customer Number of 24 and an Order Date of 1/31/98.

If you look at the indexes for the Order table in the Data Dictionary, you see that there is an index on the Order Date field, and another index that has the CustNum field as its primary component, followed by the OrderNum field. The FOR FIRST construct takes advantage of both of these indexes to resolve the request in the most efficient way possible. The FIND statement can use only one of the indexes.

The code first resets ETIME, then does the same FIND in a loop 10000 times. It then saves the ETIME counter for this operation. Then it resets it again, does a FOR FIRST 10000 times, saves that value, and finally displays both values:

DEFINE VARIABLE iCount AS INTEGER NO-UNDO.
DEFINE VARIABLE iFindTime AS INTEGER NO-UNDO.
DEFINE VARIABLE iForTime AS INTEGER NO-UNDO.

ETIME(TRUE).
DO iCount = 1 TO 10000:
  FIND Order WHERE CustNum = 3000 AND OrderDate = 3/9/23.
END.
iFindTime = ETIME.

ETIME(TRUE).
DO iCount = 1 TO 10000:
  FOR FIRST Order WHERE CustNum = 3000 AND Orderdate = 3/9/23:
  END.
END.
iForTime = ETIME.

MESSAGE "The FIND took " iFindTime " milliseconds " SKIP
  "The FOR FIRST took " iForTime VIEW-AS ALERT-BOX.
This is the result of running the code:

So, the FOR FIRST was significantly faster. The actual difference is very dependent on the actual indexes and the number of records to search.