Runtime Efficiency in COBOL

by Arnold J. Trembley , Thu-08-Jun-2000

Additional material and links were last updated Tue-18-Oct-2005.


Modern IBM mainframe COBOL compilers contain a patented optimizer that generates extremely clean and efficient code. But the compiler writers cannot read your mind and occasionally you may have issues with runtime performance efficiency. Most performance problems are caused by poor design. These problems can sometimes be corrected with simple coding changes. In extreme cases runtime performance can only be improved with a major rewrite.

In general, COBOL programs are built to solve business accounting problems. They tend to be I/O bound rather than CPU bound. One indication of a runtime performance problem may be CPU time exceeding 50% of wall-clock runtime on a batch job. Another indication may be response time in excess of one second for a CICS online program. Even if CPU utilization seems normal, you may have a runtime performance problem if a job simply takes too much time, and prevents the daily batch cycle from completing in less than 24 hours.

I have heard it said that there are only two ways to improve runtime performance: Shorten your instruction path or reduce your I/O. Or in simpler terms, don't do any work you don't need to do. Since COBOL programs are typically I/O bound, the gains from optimizing your file I/O design tend to be bigger than from shortening your instruction path. So here are some tips on best practices to reduce your I/O:

  • Use BLOCK CONTAINS 0 RECORDS in your FD (and BLKSIZE=0 in your JCL DCB parameters) to allow the OS/390 operating system to optimize your block size. These two changes ensure that the maximum number of records will be processed for a single file input/output operation.
  • Avoid multiple passes against the same file, if possible.
  • Try not to tie up too many tape drives in a single job step. If your program needs 10 tape drives, it will wait until all 10 drives are available. Try to keep files on disk whenever conveniently possible.
  • For massive changes to a key-sequenced VSAM file in batch, it is generally faster to unload to QSAM and process sequentially. Even with external sorts, tape access, and multiple steps, the CPU will do less work.
  • If you need to support multiple alternate indexes to a file, consider conversion to DB/2. DB/2 does this faster and better than VSAM.
  • If performance is absolutely critical for your application, don't be afraid to test alternate designs.

I have seen 90% reductions in wall-clock runtime, simply by optimizing the block size of a QSAM file. That means a 10-hour job can complete in one hour.

Shortening your instruction path can also improve your runtime efficiency, sometimes as dramatically as improving your I/O. Here are some tips for writing efficient procedure logic:

  • When performing arithmetic, always use signed numeric fields. COBOL performs faster with signed fields than unsigned fields. Arithmetic will be faster on binary fields than on packed-decimal fields, but not by much. Either binary or packed-decimal arithmetic is much faster than arithmetic on DISPLAY USAGE numbers.
  • For any computation more complex than ADD +1 TO RECORD-COUNT, use the COMPUTE statement rather than a mix of ADD, SUBTRACT, MULTIPLY, and DIVIDE commands. Be sure your numeric fields are wide enough to avoid truncation of intermediate results.
  • For fixed-point binary arithmetic, runtime performance will be better with the TRUNC(OPT) compile option. Don't use TRUNC(BIN), it generates a great deal of additional code to truncate results to the target picture width. It will also perform your arithmetic with packed-decimal numbers instead of binary numbers.
  • In a nested IF statement or an EVALUATE case structure, you can shorten your instruction path if you know in advance that certain conditions occur much more frequently than others. Test for these conditions early. That bypasses all the logic to test for the less common situations.
  • Watch your loops. Any code that is iterated will adversely lengthen your instruction path if it includes instructions that do not need to be executed. This is particularly important with table searches.
  • When searching a table with more than 20 items, try to use a binary search (SEARCH ALL) rather than a serial search. A serial search of a 1000-entry table is very inefficient, especially if it is performed for every input record and your file has 10 million of them.

Testing alternate designs will help identify which approach improves efficiency. Sometimes it may be helpful to examine the disassembled code generated by the compiler. In my experience, optimizing your loops and table searches will make the biggest gains.

Many years ago I assisted another programmer in an all-night session, building some one-time reports. We wrote a program that read a large file. For each record, a table was serially searched to look up customer information. The input file was large, and the customer table had over 2000 entries. We cancelled that program after one hour, because it would not finish in time. Looking at the program, we realized that the input file was in sequence by customer number. A simple test was added to see if the current customer number matched the last customer number searched for, allowing the table search to be bypassed. The modified program completed in five minutes.

Recently I worked on a production program that was having a performance problem. The program ran for 10 hours and used almost 10 hours of CPU time. For each of 15 million input records, a table with about 1000 entries was searched serially. I modified the program to use a binary search rather than a serial search. On the next execution the CPU utilization was reduced by 97% and the wall-clock runtime was reduced by eight hours.

Efficient runtime performance results from good analysis and design, but many performance problems can be repaired with relatively simple changes.

More COBOL Run-time Efficiency anecdotes

If you have an interesting story about a performance problem in COBOL, please send it to me. I would like to read it, and perhaps include it on this page.

Click Here to return to my home page.


Website copyright by Arnold J. Trembley
Last Updated Wednesday, November 9th, 2005.