You are currently on IBM Systems Media’s archival website. Click here to view our new website.


An Array of Arrays

One of the most under-utilized features of RPG IV has to be arrays. We frequently see programs that use a database lookup when an array could've served the purpose and would almost certainly have been far more efficient. For example, many of you probably have a database on your system containing the U.S. state codes and names. This, in spite of the fact that the last record to be added to the file was Hawaii in August of 1959. Not exactly a dynamic file is it?! We suspect that part of the reason for this lies in the fact that prior to V5R1, RPG didn't have a high-speed array search capability. The performance of the old LOOKUP op-code was so poor that it was often faster to use a database lookup. The advent of the %LOOKUP BIF removed this shortcoming, but old habits die hard. If you want to know more about the details behind how %LOOKUP operates read the article, "Look before you %LOOKUP."

For this article, we decided to explore the idea of using arrays for the validation of codes such as account and part numbers, GL codes, etc. Our examples demonstrate two basic approaches to the problem. The first method searches a conventional RPG array, which is loaded with all of the customer numbers present in the customer master file. The second takes a rather different approach. It takes advantage of the fact that customer numbers are indeed numbers and uses the number as the index into an array of indicators. The programs have been set up to time their operation through a number of iterations so we can compare the relative speeds of the different approaches. It may have occurred to you since both of these approaches utilize arrays, that they're constrained by RPG's limit of 32,767 elements. We'll address that issue in our third example.

Now that you know where we're headed, let's jump into our first program.

H Option(*SrcStmt:*NoDebugIO)   DftActGrp(*No)

    FcustMast  IF   E           K DISK


    D LoadCustomerNumbers...
    D                 pr            10i 0

(A) D validCustomer   s                   Like(custNo)
    D                                     Dim(32767) Ascend

    D customerCount   s             10i 0
    D searchCust      s                   Like(custNo)

    D x               s             10i 0
    D result          s             10i 0
    D loopMax         s             10i 0
    D hits            s             10i 0
    D misses          s             10i 0

    D splitTimestamp  ds
    D   timestamp                     z
    D   timePortion                 12a   Overlay(timestamp: 12)

(B) dsply 'Number of test loops to run?' '' loopMax;

    customerCount = LoadCustomerNumbers();

    For x = 1 to loopMax;

      searchCust = GetRandom( 1: 32000 );
      i = %Lookup(searchCust: validCustomer: 1: customerCount);

      if i > 0;
        hits += 1;
        misses += 1;


(C) timestamp = StopTimer();
    dsply ('Total time ' + timePortion );
    dsply ('Hits = ' + %Char(hits) + ' - Misses = ' + Char(misses) );

    *inlr = *On;


(D) P LoadCustomerNumbers...
    P                 b
    D                 pi            10i 0

    read custMast;
    Dow not %Eof( custmast );
      customerCount += 1;
      validCustomer( customerCount ) = custNo;
      read custMast;

    return customerCount;

  P LoadCustomerNumbers...
  P                 e

Jon Paris is a technical editor with IBM Systems Magazine and co-owner of Partner400.

Susan Gantner is a technical editor with IBM Systems Magazine and co-owner of Partner400.



2019 Solutions Edition

A Comprehensive Online Buyer's Guide to Solutions, Services and Education.


A Guide to Passing an Audit


A Look at COBIT Security

IBM Systems Magazine Subscribe Box Read Now Link Subscribe Now Link iPad App Google Play Store
IBMi News Sign Up Today! Past News Letters