APL and J: Some Benchmarks
Vector 8:3, page 70
Transcribed from the printed issue; not yet reviewed. Read it in the PDF of the issue, page 70
I first learned APL via a self-teach set of lessons on APL/360 in the early 70s and still have some faded notes from 1974 sellotaped into two A4 binders. I was at the time fascinated by the notation and determined to master it. What started as an experiment in my IBM days at Hursley Labs continued when I joined ICL Dataskil at Reading in 1977 and shortly after went out to join the ICL EC project in Luxembourg. There an ICL Mainframe was being introduced and work transferred to it. As this included APL I was able, as part of my job, to use APL (some people will remember the 2900 APL I’m sure), write code on a variety of machines, teach APL courses (in both English and French), and of course enjoy being a good European in the heart of the EEC. Teaching APL introduced me to a large number of fonctionaires in both Luxembourg and Brussels, some of whom have remained contacts and friends over many years. Regrettably after nearly six years I and the family returned to the UK.
Since then APL has definitely been on the back burner (there being no easily accessible APL at work) until I came across first I-APL and then J. I have been able to experiment a little with both of these languages and offer my experiences in performance comparisons using the Adrian Smith "benchmarks". At home I have an XT which has been extended with an 8087, V30 replacing 8086, 2Mb expanded memory and two SCSI drives giving me a total of 290Mb filestore. Although I have repeated some of the performance tests at work where I have a 386 and 486 machine, I have not included them all. My son’s Archimedes 410 has 4Mb mainstore, 100Mb HD and an ARM3 running at 30MHz and has been used to test the 16 and 32 bit versions of I-APL. I wish I had an APL able to exploit the power of this machine.
Having coded the Adrian Smith "benchmarks" in APL*plus, Sharp APL, I-APL, and J, I looked around for a more meaty test and settled on an APL implementation of the N Queens problem. Starting from a classical APL approach I have been attempting to rewrite my first non-optimised APL solution in J - quite an interesting task and a reasonable test of J (and me) as my APL original is heavily recursive. Since starting I have received a copy of the APL algorithm written by Roger Hui; its so much faster than mine that I shall think hard about a version in J when I have fully understood his APL code. However my version does give a solution for 10 queens where his gives me wsfull!
I am looking forward to the day when J settles down and it becomes possible to write code in workspaces of a reasonably large size. What would also be useful would be an easier way to develop functions; I still find that use of $. is difficult to grasp. Perhaps a summary example explaining how to extend a multi-line function into a conditional loop structure would help. For the moment I find that to write J takes much more intellectual effort and there is definitely a higher hurdle to jump before being able to use J than APL.
I received from Anthony Camacho the J 3.4 for the Archimedes with its rather nice integration into the desktop environment. The performance figures using the same benchmark are given below. I must also admit that the section Tutorials in the new version of the "ISI Dictionary of J" goes a long way towards explaining by example.
On balance I like using J, have a few dislikes like syntax with mandatory spaces and workspace restrictions, and hope that my wishlist for improvements will come true in 1992.
The Benchmarks¶
Here is a summary of the Adrian Smith ‘benchmark’ run on several APLs. The PC-based results are for an XT at 9.6MHz with 8087 maths co-processor (all times in ms). For comparison the I-APL results on both the PC/XT and an Archimedes are included as the last column. In some cases several runs have been averaged as the clock resolution is not that good. A few tests failed for reasons indicated.
APLplus/PC SharpAPL J J J I-APL J-Arc J-Arc I-APL(32)
Test (6.1) v17 v20 2.8 3.3 PC/XT ARM2 ARM3 ARM3
---- ----- ----- ----- ----- ----- ----- ----- ---- ------
1 165 493 494 675 675 5930 1180 360 460
2 30 110 110 55 55 800 30 30 70
3 140 1154 1153 10000 7600 6050 3160 2080 500
4 700 1400 1318 824 1900 6200 2750 880 520
5 165 355 330 110 110 5000 120 40 630
6 385 2087 2087 9500 7050 14950 2120 1370 2050
7 1300 4557 4559 limit err limit err 59430 2070 580 4580
8 30 2140 2142 360 385 990 30 10 100
9 1620 2527 2526 1483 1480 35150 270 60 2560
10 1810 355 329 2340 2400 111270 650 110 8430
11 60 163 140 21200 21620 19400 5190 2950 1240
12 100 110 55 wsfull wsfull 27400 fail fail 2380
13 150 2746 2417 2280 2200 2860 690 410 430
14 1370 25376 21751 21350 20300 25380 5240 3230 4010
15 14170 254207 217500 212100 201000 250470 51050 31320 39700
16 30 660 659 2270 2308 24320 650 320 2030
17 12750 12193 12160 58500 51200 limit err 11840 6080 30580
The essential difference between the J2.8 and J3.3 script is the use of "." instead of ".." in an inner product. A space must occur before this delimiter; an unfortunate fact for a specification which is hopefully otherwise whitespace independent. The function fn is defined with ":" or "::" in J3.3, J2.8 respectively. The Archimedes ran in mode 12 with no other multi-tasking applications.
The Original ‘Smith’ Benchmarks (in APL and in J)¶
V←1000⍴ 4 5 6 0
M←100 10 ⍴ 2.5 6.7 0 0 8 ¯5.7
S←10000⍴'THE CAT SAT ... MAT'
S[999+⍳6]←'ADRIAN'
I←100?1000
B←10000⍴V=6
FF←800 5 ⍴'TR HGHJ ...'
FF[601;]←'EJD..'
∇ FN N;CT;X
[1] CT←0
[2] LP:→(N<CT←CT+1)↑EXIT
[3] X←+/ 2 3 ⍴⍳6
[4] →LP
[5] EXIT:'DONE'
∇
v=.1000$4 5 6 0
m=.100 10$2.5 6.7 0 0 _5.7
s=.10000$'the ... '
s=. 'adrian' (999+i.6) }s
i=.100?1000
b=.10000$v=6
ff=.4000$'tr ... '
ff=.800 5$'ejd..' (3000+i.5)}ff
APL Expression Type | J Expression
-------------- ---- | ------------
1. +/V+V ⍝ INT | +/v+v
2. +/V[I] ⍝ INT | +/i{v
-----------------------------------|------------------------
3. V+.×V ⍝ REAL | v+/ .*v
4. +/V*2 ⍝ REAL | +/v^2
5. X←+/M ⍝ REAL | x=.+/m
6. V+.×,M ⍝ REAL | v+/ .*,m
-----------------------------------|------------------------
7. +/S='T' ⍝ CHAR | +/s='t'
8. 'FAT'∊S ⍝ CHAR | 'fat'e. s
9. X←S∊'FAT' ⍝ CHAR | x=.s e. 'fat'
-----------------------------------|------------------------
10. X←B∨B∧~B ⍝ BOOL | x=.b +. b *. -. b
11. ∧/B ⍝ BOOL | *./b
12. X←∨\B ⍝ BOOL | x=.+/.\b
-----------------------------------|------------------------
13. FN 10 ⍝ FN | fn 10
14. FN 100 ⍝ FN | fn 100
15. FN 1000 ⍝ FN | fn 1000
-----------------------------------|------------------------
16. X←FF∧.='EJD..' ⍝ IP | x=. *./ff='ejd..'
17. X←FF∧.=⍉20 5⍴'EJD..' ⍝ IP | x=. ff*./ .= |:20 5$'ejd..'