Pages

Friday, November 5, 2010

COBOL Performance Tuning - Large Arrays

When initializing large arrays with default values, most programmers will perform a paragraph or internal loop, moving the default values to each field of each occurs until all of the occurrences are populated.  This is not necessarily the most efficient way to perform this task.

One way to perform this task more efficiently is to move your default values to the fields of the first occurrence.  Then move that first group of occurs to the second group (as a block, not as individual fields).  Then move the first two group of occurs to the third and fourth.  Then move the first four group of occurs to the next four, and so on and so on.  Be careful when you get to the end of your occurs that you do not move data beyond the end of your array, or you will likely clobber code.

Here is a quick example:

01  EXAMPLE-TABLE.
    05  MY-TABLE.
        10  TABLE-ENTRY OCCURS 999 TIMES.
            15  FIRST-NAME         PIC X(15).
            15  LAST-NAME          PIC X(15).
            15  SEX-CODE           PIC X.
            15  DOB.
                20  DOB-YYYY       PIC 9(4).
                20  DOB-MM         PIC 99.
                20  DOB-DD         PIC 99.
            15  SSN                PIC 9(9).
            15  SALARY             PIC S9(9)V99 COMP-3.
...
    MOVE SPACES TO MY-TABLE.
    MOVE ZEROS TO DOB
                  SSN
                  SALARY.
    MOVE MY-TABLE (1:54)
      TO MY-TABLE (55:54).
    MOVE MY-TABLE (1:108)
      TO MY-TABLE (109:108).
    MOVE MY-TABLE (1:216)
      TO MY-TABLE (217:216).

You obviously do not want to hard code like in the example above, but this shows the concept in a simple form. You would want to make your start position and length variable fields and perform this in a loop. How you code it is up to you.

The routine I am familiar with became more efficient than the typical performed loop at about 15 occurs. Yours may differ. You may have to look at the assembler code generated to make that determination. 

If anyone has other techniques to populate large arrays, please share them in a comment or email the concept to me and I'll post it on this blog.

6 comments:

  1. What do you think about:

    INITIALIZE TABLE-ENTRY(1)
    MOVE MY-TABLE TO MY-TABLE(LENGTH OF TABLE-ENTRY + 1:)

    ReplyDelete
    Replies
    1. That is a slick little command. I had to look up how that works, since I have always given it a length to move. Then when I read what it does (determines the length automatically), I thought for sure it would just move the first occurrence to the second occurrence and leave the rest of MY-TABLE blank, but it did indeed end up leaving the table initialize as we want it.

      However, with shortcuts like this, there are often drawbacks. So I had to test it out and get measurements. I did your two commands one million times, then did the same thing using the routine I mentioned one million times.

      Results - Your two commands: 13.49 CPU & 22.63 elapsed time.

      The way I mentioned: 2.75 CPU and 4.24 elapsed time.

      Your two commands, though easy to code, is 5 times slower and more costly.

      Delete
  2. I can not to test yet, but if you redefine all the table as 54 * 999 bytes to a new variable PIC X(53946) or a group of only alphanumeric field such the sum of length is equal to 53946 and then
    MOVE ZEROS TO ALL FIELD OR FIELDS OF THE NEW REDEFINITION?
    all they will have '0' but in your code you will need to accept that any alpha field will have a chain of '00000000' not space, numeric will be zero.
    But in any way when you execute MOVE 'NAME' to FIRST-NAME(n) the '0' chain will be over writed.

    ReplyDelete
    Replies
    1. This is an option as long as:
      1. You are moving something to all of your alphanumeric fields
      2. You don't mind zeros in any FILLER areas
      3. None of your numeric fields are COMP, COMP-3, etc.

      You wouldn't have to redefine the table, just move all zeros to the 01 level.

      Delete
  3. What about putting 05s with values above 05 my-table. Then moving example-table to my-table?

    ReplyDelete
    Replies
    1. I'm not sure if I completely follow where you're going with that. Can you give me an example in pseudo code?

      Delete