Original post is here: eklausmeier.goip.de
When I ran the n-queens problem in COBOL using GnuCOBOL I was a little bit surprised how slow the resulting program was -- it was slower than the equivalent PHP program. Therefore I installed the IBM COBOL for Linux compiler on the same machine and compared performance, see Installing IBM COBOL for Linux on Arch Linux. The IBM compiler generated program was 17-times faster!
Here are the results in seconds (real) on an Intel NUC.
Program | runtime |
---|---|
GnuCOBOL | 6.33 |
IBM COBOL | 0.37 |
I reproduce the previous results Performance Comparison C vs. Java vs. Javascript vs. LuaJIT vs. PyPy vs. PHP vs. Python vs. Perl:
Language | NUC | Ryzen | Odroid |
---|---|---|---|
C | 0.17 | 0.15 | 0.44 |
Java 1.8.0 | 0.31 | 0.22 | 108.17 |
node.js 16.4 | 0.34 | 0.21 | 1.67 |
LuaJIT | 0.49 | 0.33 | 2.06 |
PyPy3 7.3.5 | 1.57 | 0.86 | n/a |
PHP 8 | 3.23 | 2.35 | 42.38 |
Python 3.9.6 | 12.29 | 7.65 | 168.17 |
Perl 5.34 | 25.87 | 21.14 | 209.47 |
I compiled the COBOL program with GnuCOBOL using cobc -O2 -x
, and for IBM COBOL I used cob2 -q'OPTIMIZE(FULL)'
. Running the two programs is:
1$ time xdamcnt 1 12
So the GnuCOBOL program is slower than almost everything except Python and Perl. While the IBM COBOL is two times slower than the C program and in the range of Java and JavaScript, but still faster than LuaJIT. The slow performance of GnuCOBOL was not expected, while the performance of IBM COBOL is inline with expectations.
Some notes on comparison:
- Performancewise IBM COBOL is a welcome alternative to GnuCOBOL. On the other hand IBM COBOL is 32-bit with all its shortcomings. As I remarked in Memory Limitations with IBM Enterprise COBOL Compiler: No big-data with IBM COBOL.
- GnuCOBOL is way more permissive with its input format than IBM COBOL, which is still very mainframe oriented.
- Also GnuCOBOL offers an easier way to handle command-line arguments. Command-line handling in IBM COBOL is a little bit brittle, although it is not in any way difficult.
- GnuCOBOL runs on ARM, while IBM COBOL is x86 only. So IBM COBOL will not run on Graviton or Ampere.
Here is the COBOL program used for the tests:
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. xdamcnt.
3 AUTHOR. Elmar Klausmeier.
4 DATE-WRITTEN. 03-Oct-2021.
5 *
6 * entworfen am 31.03.1985
7 * geschrieben am 02.04.1985
8 * revidiert am 18.04.1985
9 * Umgeschrieben auf COBOL: 03.10.2021
10 *
11 * 2 4 6 8 10 12 14
12 * 1 0 0 2 10 4 40 92 352 724 2680 14200 73712 365596
13 *
14 DATA DIVISION.
15 WORKING-STORAGE SECTION.
16 77 i pic 9(8) comp-5.
17 77 j pic 9(8) comp-5.
18 77 k pic 9(8) comp-5.
19 77 N pic 9(8) comp-5.
20 77 N2 pic 9(8) comp-5.
21 77 l pic s9(8) comp-5.
22 77 z pic 9(8) comp-5.
23 77 configOKret pic 9(8) comp-5.
24 01 A_vector.
25 10 A pic 9(8) comp-5 occurs 100 value 0.
26 77 istart pic 9(8) comp-5 VALUE 1.
27 77 iend pic 9(8) comp-5 VALUE 0.
28 77 cnt pic 9(8) comp-5 VALUE 0.
29 77 slen pic 9(8) comp-5 value 0.
30 77 argc pic 9(8) comp-5 VALUE 0.
31 77 argv PIC X(100) VALUE SPACES.
32
33 LINKAGE SECTION.
34 *01 argc pic s9(8) comp-5.
35 *01 argv.
36 * 02 argvTable OCCURS 1 TO 100 TIMES DEPENDING ON argc.
37 * 03 pargv pointer.
38 *01 argviStr pic x(8).
39
40 PROCEDURE DIVISION.
41 *PROCEDURE DIVISION USING BY VALUE argc BY REFERENCE argv.
42 Pmain section.
43 DISPLAY "N-Queens Problem in COBOL".
44 display ' 2 4 6 8 10 12 14'.
45 display '1 0 0 2 10 4 40 92 352 724 2680 14200 73712 365596'.
46
47 * GnuCOBOL command line handling
48 ACCEPT argc from ARGUMENT-NUMBER.
49 display "argc=", argc.
50 if argc >= 1 then
51 ACCEPT iend FROM ARGUMENT-VALUE.
52 if iend <= 0 or iend > 14 then
53 move 10 to iend
54 end-if.
55 if argc >= 2 then
56 move iend to istart
57 accept iend from argument-value
58 end-if.
59
60 * IBM COBOL command line handling
61 * display "argc=", argc.
62 * if argc > 1 then
63 * set address of argviStr to pargv(2)
64 * move zero to slen
65 * inspect argviStr tallying slen for characters
66 * before initial X"00"
67 * move argviStr(1:slen) to iend
68 * if iend <= 0 or iend > 14 then
69 * move 10 to iend
70 * end-if.
71 * if argc > 2 then
72 * move iend to istart
73 * set address of argviStr to pargv(3)
74 * move zero to slen
75 * inspect argviStr tallying slen for characters
76 * before initial X"00"
77 * move argviStr(1:slen) to iend
78 * end-if.
79
80 display "istart=", istart, " iend=", iend.
81
82 PERFORM VARYING i FROM istart BY 1 UNTIL i > iend
83 perform nqsolve
84 DISPLAY "D(", i, ") = ", cnt
85 END-PERFORM.
86
87 STOP RUN.
88
89
90
91 * Return number of positions for N queens.
92 nqsolve section.
93 move zero to cnt.
94 move 1 to k.
95 move 1 to A(1).
96 move i to N.
97 move i to N2.
98
99 lloop.
100 perform configOK.
101 if configOKret = 1 then
102 if k < N then
103 add 1 to k
104 move 1 to A(k)
105 go to lloop
106 else
107 add 1 to cnt
108 end-if
109 end-if.
110
111 perform with test after varying k from k by -1 until k <= 1
112 if A(k) < N then
113 add 1 to A(k)
114 go to lloop
115 end-if
116 end-perform.
117
118 add 1 to A(1).
119 if A(1) > N2 then
120 exit section
121 end-if.
122 move 2 to k.
123 move 1 to A(2).
124 go to lloop
125
126 exit.
127
128
129
130 * Check if k-th queen is attacked by any other prior queen.
131 * Return nonzero if configuration is OK, zero otherwise.
132 configOK section.
133 move zero to configOKret.
134 move A(k) to z.
135
136 perform varying j from 1 by 1 until j >= k
137 compute l = z - A(j)
138 if l = 0 then
139 exit section
140 end-if
141 if l < 0 then
142 compute l = 0 - l
143 end-if
144 if l = k - j then
145 exit section
146 end-if
147 end-perform.
148
149 move 1 to configOKret.
150
151 exit.
152
153
Added 01-Sep-2024: Referenced in Performance of GnuCOBOL: A free COBOL compiler.