For a million IFs less



Support for OS/VS COBOL, VS COBOL II, COBOL for OS/390 & VM and Enterprise COBOL for z/OS

For a million IFs less

Postby polparioritsas » Fri Sep 28, 2018 10:17 pm

One of the first you learn in #Cobol, especially back in the day when indexed files where a common practice, is the use of SW-FIRST-READ.

In a program flow most probably there’s a loop on a cursor or a file. Many programmers inside that main loop they use an IF for controlling the first read. For example, if you want to match previous and current row/record. The COBOL code would be something like:

01 SW-FIRST-READ PIC X VALUE ‘Y’.

  88 FIRST-READ-YES   VALUE ‘Y’.
  88 FIRST-READ-NOT   VALUE ‘N’.
MAIN-ROUTE.
   PERFORM READ-ROUTE
   #PERFORM UNTIL EOF
     #IF FIRST-READ-YES
        SET FIRST-READ-NOT TO TRUE
        MOVE CURRENT-RECORD TO PREVIOUS-RECORD
     END-IF
     IF CURRENT-RECORD = PREVIOUS-RECORD
        DISPLAYSAME ACCOUNT’
        PERFORM SAME-ACCOUNT-ROUTE
     ELSE
        DISPLAYNEW ACCOUNT’
        PERFORM NEW-ACCOUNT-ROUTE
     END-IF
     PERFORM READ-ROUTE
   END-PERFORM
  IF EOF AND SW-FIRST-READ
      DISPLAYNO RECORDS/ROWS IN FILE/CURSOR
      PERFORM EMPY-FILE-OR-CURSOR-ROUTE
   END-IF .
READ-ROUTE.
    READ FILE NEXT AT END SET SW-EOF TO TRUE
(OR)
   FETCH CURSOR
   IF SQLCODE = NOT-FOUND-NEXT
      SET SW-EOF TO TRUE
   END-IF
 IF SQLCODE/FILE-STATUS NOT-OK
      ERROR-HANDLING-ROUTE
    END-IF.
 

This is a very common practice with one fault for performance. The IF SW-FIRST-READ will execute as many times as the ROWS/RECORDS of the CURSOR/FILE – 1.000.000 or 50.000.000 times, and IF statement is not a fast one.

My recommendation would have some more code to be written, some paragraph rearrangements and involve a bit more thinking. But it will have 1.000.000 IFs less.

You will have to have separate paragraphs for #READ / #FETCH, for error handling and PERFORM these paragraphs twice, once before the main loop. That one would be the first time and will be executed only once. There’s no need to ask again. The code would look like this:


MAIN-ROUTE.
   PERFORM READ-ROUTE
   IF NOT-EOF
      MOVE CURRENT-RECORD TO PREVIOUS-RECORD
   ELSE
      DISPLAYNO RECORDS/ROWS IN FILE/CURSOR
      PERFORM EMPY-FILE-OR-CURSOR-ROUTE
   END-IF
   PERFORM UNTIL EOF
     IF CURRENT-RECORD = PREVIOUS-RECORD
        DISPLAYSAME ACCOUNT’
        PERFORM SAME-ACCOUNT-ROUTE
     ELSE
        DISPLAYNEW ACCOUNT’
        PERFORM NEW-ACCOUNT-ROUTE
     END-IF
   END-PERFORM
  PERFORM END-ROUTE  .
READ-ROUTE.
   READ FILE NEXT AT END SET SW-EOF TO TRUE
(OR)
   #FETCH #CURSOR
   IF SQLCODE = NOT-FOUND-NEXT
      SET SW-EOF TO TRUE
   END-IF
   IF SQLCODE/FILE-STATUS NOT-OK
      #ERRORHANDLING-ROUTE
    END-IF.
 
polparioritsas
 
Posts: 3
Joined: Tue Nov 28, 2017 12:28 am
Has thanked: 0 time
Been thanked: 0 time

Re: For a million IFs less

Postby enrico-sorichetti » Sat Sep 29, 2018 12:43 am

when You post code, learn how to use the code tag
it will make Your snippet more readable

edited Your post and done it for You
cheers
enrico
When I tell somebody to RTFM or STFW I usually have the page open in another tab/window of my browser,
so that I am sure that the information requested can be reached with a very small effort
enrico-sorichetti
Global moderator
 
Posts: 3006
Joined: Fri Apr 18, 2008 11:25 pm
Has thanked: 0 time
Been thanked: 165 times

Re: For a million IFs less

Postby polparioritsas » Sat Sep 29, 2018 1:43 am

thank you.
polparioritsas
 
Posts: 3
Joined: Tue Nov 28, 2017 12:28 am
Has thanked: 0 time
Been thanked: 0 time


Return to IBM Cobol