Wednesday, March 21, 2012

COBOL Code Optimization

To assist in the optimization of the code, you should use the OPTIMIZE compiler option. With the
OPTIMIZE(STD) or OPTIMIZE(FULL) options in effect, you may receive optimizations that include:
  • eliminating unnecessary branches
  • simplifying inefficient branches
  • simplifying the code for the out-of-line PERFORM statement, moving the performed paragraphs in-line,where possible
  • simplifying the code for a CALL to a contained (nested) program, moving the called statements in-line,where possible
  • eliminating duplicate computations
  • eliminating constant computations
  • aggregating moves of contiguous, equal-sized items into a single move
  • deleting unreachable code
Additionally, with the OPTIMIZE(FULL) option in effect, you may also receive these optimizations:
  • deleting unreferenced data items and the associated code to initialize their VALUE clauses
Many of these optimizations are not available with OS/VS COBOL, but are available with IBM Enterprise
COBOL. NOOPTIMIZE is generally used while a program is being developed when frequent compiles are necessary. NOOPTIMIZE can make it easier to debug a program since code is not moved. However, IBM Enterprise COBOL now supports debugging programs compiled with the OPTIMIZE compiler option.
OPTIMIZE requires more CPU time for compiles than NOOPTIMIZE, but generally produces more
efficient run-time code. For production runs, OPTIMIZE is recommended.

WARNING: If your program relies upon unreferenced level 01 or level 77 data items, you should not use
OPTIMIZE(FULL), since OPTIMIZE(FULL) will delete all unreferenced data items. One way to prevent
the data item from being deleted by the OPTIMIZE(FULL) option is to refer to the data item in the
PROCEDURE DIVISION (for example, initialize the data item with a PROCEDURE DIVISION
statement instead of with VALUE clauses).

Performance considerations using OPTIMIZE:
  • On the average, OPTIMIZE(STD) was 1% faster than NOOPTIMIZE, with a range of 7% faster to equivalent.
  • On the average, OPTIMIZE(FULL) was equivalent to OPTIMIZE(STD).

ARITH Compiler Option

ARITH affects the maximum number of digits that you can code for integers, and the number of digits used in fixed-point intermediate results. By specifying ARITH complier option we can control the maximum number of digits allowed for decimal numbers (packed decimal, zoned decimal and numeric-edited data items and numeric literals).
 
ARITH(EXTEND)  - Max. Number of digits 31.
ARITH(COMPAT) - Max. Number of digits 18.
 
Default is: ARITH(COMPAT)

Abbreviations are: AR(C|E)

Arith-extend is performance hampering because of larger intermediate results.

When you specify ARITH(EXTEND):
  • The maximum number of digit positions that you can specify in the PICTURE clause for packed-decimal, external-decimal, and numeric-edited data items is raised from 18 to 31.
  • The maximum number of digits that you can specify in a fixed-point numeric literal is raised from 18 to 31. You can use numeric literals with large precision anywhere that numeric literals are currently allowed, including:
    • Operands of PROCEDURE DIVISION statements
    • VALUE clauses (for numeric data items with large-precision PICTURE)
    • Condition-name values (on numeric data items with large-precision PICTURE)
  • The maximum number of digits that you can specify in the arguments to NUMVAL and NUMVAL-C is raised from 18 to 31.
  • The maximum value of the integer argument to the FACTORIAL function is 29.
  • Intermediate results in arithmetic statements use extended mode.
When you specify ARITH(COMPAT):
  • The maximum number of digit positions in the PICTURE clause for packed-decimal, external-decimal, and numeric-edited data items is 18.
  • The maximum number of digits in a fixed-point numeric literal is 18.
  • The maximum number of digits in the arguments to NUMVAL and NUMVAL-C is 18.
  • The maximum value of the integer argument to the FACTORIAL function is 28.
  • Intermediate results in arithmetic statements use compatibility mode.

Converting a file from VB to FB.

DFSORT can be used to do VB to FB conversion, when sorting, copying or merging. The VTOF or CONVERT and OUTREC operands of OUTFIL can be used to change variable-length (e.g. VB) input records to fixed-length (e.g. FB) output records. VTOF or CONVERT indicates that conversion is to be performed and OUTREC defines the reformatted records. All output data sets for which VTOF or CONVERT is used must have or will be given fixed-length record formats.

An example of OUTFIL conversion:
//VTOF EXEC PGM=SORT
//SYSPRINT DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//SYSDUMP DD SYSOUT=*
//SORTIN DD DSN=M145.TEMP.SORT.IN,DISP=SHR
//SORTOUT DD DSN=M145.TEMP.SORT.OUT,
// DISP=(NEW,CATLG,DELETE),UNIT=DASD,
// SPACE=(TRK,(500,500),RLSE),
// DCB=(RECFM=FB,LRECL=80)
//SYSIN DD *
            SORT FIELDS=COPY
            OUTFIL FNAMES=SORTOUT,VTOF,OUTREC=(5,80),VLFILL=C'*'
//*
The above step will copy the records from SORTIN to SORTOUT. If the input records are shorter than 80 bytes, the output is padded with ‘*’ (Specified by VLFILL).

If VLFILL option is not specified, by default the records are padded with spaces.

VLFILL=C’x’ => pad with the character x.
VLFILL=X’yy’ => pad with hexadecimal character X’yy’.

Recovering Deleted Flat Files

Flat files can be recovered by following the below mentioned steps.

  1. Start 6 
  2. HLIST BCDS DSN('filename') 
  3. Wait for the system notification
  4. Type the command HRECOVER 'filename' and wait for system notification

Different variations of HRECOVER are given below.
  • HRECOVER 'filename' recovers with same name
  • HRECOVER ‘old filename’ NEW ('new filename') recovers and assigns new name
  • HRECOVER 'file name' REPLACE recovers replacing a file with same name

The recovery might take some time. You should have HSM volume dump(s) of the volume(s) where the dataset resided for HRECOVER to work successfully. Else you will recive a message "BACKUP/DUMP COPY DOES NOT EXIST".

AUTOTYPE Suggestion

How wonderful it feels when Internet explorer suggests names for URLs when we start typing the first few letters!

Our mainframe also has the ability to do pretty much the same. Using ‘KEYS’ command on the command line, assign a free PF key with the value ‘AUTOTYPE’. We are all set.


Now use 3.4 to go to the Data Set list utility and then type the first few qualifier of the required data set. Press the desired PF key. It will show you the dataset name which is nearest match.