A Matter of Time - Part 1 - Introduction
Back again to build a version of the TDF_LAP() Timing function in COBOL. This is a set of 21 timing entries used to easily monitor timings for embedded or stand-alone routines or SQL statements.
Flashback: LEGO Guy Loves Assembler
Of course the LEGO Guy loves Assembler - virtually building programs brick by brick - but he also likes to warm up with other languages - this time COBOL. After building the lapse routine - TDF-LAP - he'll give it a quick test run. Just a main process that calls another one - with the nested timings produced for each.
Sample Log Output:
This version displays the level along with BEG/END times, lapsed time and the message.
TDF-LAP Function (Procedure) - TDFPROC.CPY
*****************************************************************
* TDF LAP - LAPSE BETWEEN BEGIN/END TIMES (SQL TIMINGS) *
*****************************************************************
* *
* FIELD I/O DESCRIPTION *
* ----------------- --- ---------------------------------- *
* TDX-LAP-OPER I OPERATION TYPE (BEG/END) *
* TDX-LAP-LEV I LAPSE INDEX SET (0 THRU 20) *
* TDX-LAP-MSG I DISPLAY MESSAGE TEXT *
* TDX-LAP-DIFF O BEG/END LAPSE IN SECONDS *
* TDX-LAP-TXT-HMS O BEG/END LAPSE IN HHHH:MM:SS.SSSSS *
* *
*****************************************************************
* *
* EXAMPLE: *
* ---------------------------------------------------------- *
* MOVE 0 TO TDX-LAP-LEV *
* MOVE 'BEG' TO TDX-LAP-OPER *
* PERFORM TDF-LAP *
* <snip> *
* MOVE 0 TO TDX-LAP-LEV *
* MOVE 'END' TO TDX-LAP-OPER *
* MOVE 'PROCESS-MAIN' TO TDX-LAP-MSG *
* PERFORM TDF-LAP *
* ---------------------------------------------------------- *
* RESULTS: *
* L(00) BEG(2024:12:17_16:41:42) END(2024:12:17_16:41:43) - *
* HMS(0000:00:01.35000) MSG: PROCESS-MAIN *
* ---------------------------------------------------------- *
* *SINGLE LINE DISPLAYED FOR EACH NESTED LEVEL* *
*****************************************************************
TDF-LAP.
IF TDX-LAP-LEV-OK
COMPUTE TDX-LAP-IDX = TDX-LAP-LEV + 1
MOVE FUNCTION CURRENT-DATE TO TDX-LAP-END(TDX-LAP-IDX)
IF TDX-LAP-OPER-END
MOVE TDX-LAP-BEG(TDX-LAP-IDX) TO TDX-SEC-IN
PERFORM TDF-SECONDS
MOVE TDX-SEC-OUT TO TDX-LAP-BEG-SEC
MOVE TDX-SEC-IN( 1:4) TO TDX-LAP-TXT-BEG-Y
MOVE TDX-SEC-IN( 5:2) TO TDX-LAP-TXT-BEG-M
MOVE TDX-SEC-IN( 7:2) TO TDX-LAP-TXT-BEG-D
MOVE TDX-SEC-IN( 9:2) TO TDX-LAP-TXT-BEG-H
MOVE TDX-SEC-IN(11:2) TO TDX-LAP-TXT-BEG-I
MOVE TDX-SEC-IN(13:2) TO TDX-LAP-TXT-BEG-S
MOVE TDX-LAP-END(TDX-LAP-IDX) TO TDX-SEC-IN
PERFORM TDF-SECONDS
MOVE TDX-SEC-OUT TO TDX-LAP-END-SEC
MOVE TDX-SEC-IN( 1:4) TO TDX-LAP-TXT-END-Y
MOVE TDX-SEC-IN( 5:2) TO TDX-LAP-TXT-END-M
MOVE TDX-SEC-IN( 7:2) TO TDX-LAP-TXT-END-D
MOVE TDX-SEC-IN( 9:2) TO TDX-LAP-TXT-END-H
MOVE TDX-SEC-IN(11:2) TO TDX-LAP-TXT-END-I
MOVE TDX-SEC-IN(13:2) TO TDX-LAP-TXT-END-S
COMPUTE TDX-LAP-DIFF = TDX-LAP-END-SEC
- TDX-LAP-BEG-SEC
MOVE TDX-LAP-DIFF TO TDX-HMS-SEC
PERFORM TDF-HMS
MOVE TDX-LAP-LEV TO TDX-LAP-TXT-LEV
MOVE TDX-HMS-TXT TO TDX-LAP-TXT-HMS
MOVE TDX-LAP-MSG TO TDX-LAP-TXT-MSG
DISPLAY TDX-LAP-TXT
END-IF
MOVE FUNCTION CURRENT-DATE TO TDX-LAP-BEG(TDX-LAP-IDX)
ELSE
DISPLAY '***ERROR - LEVELS 0 THRU 20 ONLY***'
END-IF
.
TDF-LAP-EXIT.
EXIT.
*****************************************************************
An additional function - TDF-SECONDS - is used to convert the dates to seconds. The intrinsic function INTEGER-OF-DATE returns the number of days since January 1, 1601 for both BEG/END values. The days are converted to seconds with a full day being removed. The time (Hours, minutes, seconds) are then converted and added to the total seconds. This allows an accurate lapsed time to be calculated by the TDF-LAP primary function.Yet one more function is utilized to convert the lapsed seconds into HHHH:MI.SS.SSSSS format - TDF-HMS.
* TDF SECONDS - CONVERT FULL DATE FIELD TO SECONDS *
*****************************************************************
* *
* FIELD I/O DESCRIPTION *
* ----------------- --- ---------------------------------- *
* TDX-SEC-IN I FULL 20 CHARACTER DATE/TIME FIELD *
* TDX-SEC-OUT O CONVERSION TO SECONDS *
* *
*****************************************************************
* *
* EXAMPLE: *
* ---------------------------------------------------------- *
* MOVE FUNCTION CURRENT-DATE TO TDX-SEC-IN *
* PERFORM TDF-SECONDS *
* DISPLAY 'SECONDS: ' TDX-SEC-OUT *
* ---------------------------------------------------------- *
* RESULTS: 2024121715132474+050 => 013379008404.74000 *
* *
*****************************************************************
TDF-SECONDS.
COMPUTE TDX-SEC-INT
= FUNCTION INTEGER-OF-DATE(TDX-SEC-DATE)
COMPUTE TDX-SEC-OUT
= (TDX-SEC-INT * (24*60*60))
- (24*60*60)
+ (TDX-SEC-HH * 3600)
+ (TDX-SEC-MI * 60)
+ (TDX-SEC-SS)
+ (TDX-SEC-MS / 100)
.
TDF-SECONDS-EXIT.
EXIT.
*****************************************************************
This stand-alone function simply converts seconds into a more readable format - Hours, Minutes and Seconds. This will appear on the TDF-LAP Timing Log Output.
* TDF HMS - CONVERT SECONDS TO HHHH:MM:SS.SSSSS FORMAT *
*****************************************************************
* *
* FIELD I/O DESCRIPTION *
* ----------------- --- ---------------------------------- *
* TDX-HMS-SEC I NUMBER OF SECONDS *
* TDX-HMS-TXT O OUTPUT STRING: HHHH:MM:SS.SSSSS *
* *
*****************************************************************
* *
* EXAMPLE: *
* ---------------------------------------------------------- *
* MOVE 22506.256 TO TDX-HMS-SEC *
* PERFORM TDF-HMS *
* DISPLAY " OUT: " TDX-HMS-TXT *
* ---------------------------------------------------------- *
* RESULTS: 0006:15:06.25600 (22506.256 SECONDS) *
* *
*****************************************************************
TDF-HMS.
COMPUTE TDX-HMS-HH = TDX-HMS-SEC / 3600
COMPUTE TDX-HMS-SEC = TDX-HMS-SEC
- (TDX-HMS-HH * 3600)
COMPUTE TDX-HMS-MM = TDX-HMS-SEC / 60
COMPUTE TDX-HMS-SEC = TDX-HMS-SEC
- (TDX-HMS-MM * 60)
COMPUTE TDX-HMS-SS = TDX-HMS-SEC
MOVE TDX-HMS-HH TO TDX-HMS-TXT-HH
MOVE TDX-HMS-MM TO TDX-HMS-TXT-MM
MOVE TDX-HMS-SS TO TDX-HMS-TXT-SS
.
TDF-HMS-EXIT.
EXIT.
*****************************************************************
The working storage fields/arrays are contained in the TDFWORK.CPY copybook.
* TDF FUNCTION PARAMETERS / WORKING STORAGE *
*****************************************************************
01 TDX-HMS-PARMS.
05 TDX-HMS-SEC PIC 9(12)V9(5) COMP-3.
05 TDX-HMS-HH PIC 9(6) COMP-3.
05 TDX-HMS-MM PIC 9(3) COMP-3.
05 TDX-HMS-SS PIC 9(3)V9(5) COMP-3.
05 TDX-HMS-TXT.
10 TDX-HMS-TXT-HH PIC 9(4).
10 FILLER PIC X VALUE ':'.
10 TDX-HMS-TXT-MM PIC 9(2).
10 FILLER PIC X VALUE ':'.
10 TDX-HMS-TXT-SS PIC 9(2).9(5).
01 TDX-SECONDS-PARMS.
05 TDX-SEC-INT PIC 9(8).
05 TDX-SEC-OUT PIC 9(16)V9(5) COMP-3.
05 TDX-SEC-IN.
10 TDX-SEC-DATE PIC 9(8).
10 TDX-SEC-TIME.
15 TDX-SEC-HH PIC 9(2).
15 TDX-SEC-MI PIC 9(2).
15 TDX-SEC-SS PIC 9(2).
15 TDX-SEC-MS PIC 9(2).
10 TDX-SEC-GMT PIC S9(4).
01 TDX-LAP-PARMS.
05 TDX-LAP-OPER PIC X(3).
88 TDX-LAP-OPER-BEG VALUE 'BEG'.
88 TDX-LAP-OPER-END VALUE 'END'.
05 TDX-LAP-LEV PIC 99.
88 TDX-LAP-LEV-OK VALUES 0 THRU 20.
05 TDX-LAP-MSG PIC X(50).
05 TDX-LAP-BEG-SEC PIC 9(12)V9(5) COMP-3.
05 TDX-LAP-END-SEC PIC 9(12)V9(5) COMP-3.
05 TDX-LAP-DIFF PIC 9(12)V9(5) COMP-3.
05 TDX-LAP-IDX PIC 99.
05 TDX-LAP-MTX OCCURS 21 TIMES.
10 TDX-LAP-BEG PIC X(20).
10 TDX-LAP-END PIC X(20).
05 TDX-LAP-TXT.
10 FILLER PIC X(2) VALUE 'L('.
10 TDX-LAP-TXT-LEV PIC 99.
10 FILLER PIC X(6) VALUE ') BEG('.
10 TDX-LAP-TXT-BEG-Y PIC 9999.
10 FILLER PIC X VALUE ':'.
10 TDX-LAP-TXT-BEG-M PIC 99.
10 FILLER PIC X VALUE ':'.
10 TDX-LAP-TXT-BEG-D PIC 99.
10 FILLER PIC X VALUE '_'.
10 TDX-LAP-TXT-BEG-H PIC 99.
10 FILLER PIC X VALUE ':'.
10 TDX-LAP-TXT-BEG-I PIC 99.
10 FILLER PIC X VALUE ':'.
10 TDX-LAP-TXT-BEG-S PIC 99.
10 FILLER PIC X(6) VALUE ') END('.
10 TDX-LAP-TXT-END-Y PIC 9999.
10 FILLER PIC X VALUE ':'.
10 TDX-LAP-TXT-END-M PIC 99.
10 FILLER PIC X VALUE ':'.
10 TDX-LAP-TXT-END-D PIC 99.
10 FILLER PIC X VALUE '_'.
10 TDX-LAP-TXT-END-H PIC 99.
10 FILLER PIC X VALUE ':'.
10 TDX-LAP-TXT-END-I PIC 99.
10 FILLER PIC X VALUE ':'.
10 TDX-LAP-TXT-END-S PIC 99.
10 FILLER PIC X(6) VALUE ') HMS('.
10 TDX-LAP-TXT-HMS PIC X(16).
10 FILLER PIC X(7) VALUE ') MSG: '.
10 TDX-LAP-TXT-MSG PIC X(50).
*****************************************************************
Test all 21 nested timings:
Here's a simple COBOL procedure that loops 21 times to populate BEG times for nested levels 0 thru 20. Then it loops an additional 21 times to populate the END times for levels 20 down to 0. A log entry will be printed for each END operation. The LAPSE-LOOP just creates a delay - otherwise the timings will vary in microseconds only.
PERFORM UNTIL TDX-LAP-LEV > 20
MOVE 'BEG' TO TDX-LAP-OPER
PERFORM TDF-LAP
ADD 1 TO TDX-LAP-LEV
PERFORM LAPSE-LOOP
END-PERFORM
PERFORM LAPSE-LOOP
MOVE 21 TO TDX-LAP-LEV
PERFORM UNTIL TDX-LAP-LEV <= 0
PERFORM LAPSE-LOOP
SUBTRACT 1 FROM TDX-LAP-LEV
MOVE 'END' TO TDX-LAP-OPER
MOVE 'LEVEL TEST' TO TDX-LAP-MSG
PERFORM TDF-LAP
END-PERFORM
Full Test Output:
Running the test program TDDATE through OpenCobolIDE - the results are printed to the log.
Success! BEG/END times are registered for each level along with lapsed time. The first test loop set the BEG times while the second test loop marked the END and produced the output. Each level listed is a subset of the next with 20 being the lowest nest and 0 the primary. The entry levels can be used in any fashion - nested or not.
That's the end of the COBOL Timing Demonstration - Up next PC/370 Assembler.