Benchmarking Basic on Vintage Computers

There are a few machines I'm quite interested in comparing so I decided to create a simple Basic benchmark to get an idea of their relative speed. The benchmark tests 7 aspects and is inspired by qsbb, which is included with the qlay Sinclair QL emulator. The Basic source code for all the machines tested is available in the GitHub repo. I chose Basic because it was available on all the machines I wanted to test and because the versions I created for each machine would require few changes.

Benchmarks are only ever a test of what you are benchmarking and there are often other tasks that the machines would do much better at. In this case because all the benchmarks are written in Basic they are a test of both the hardware and the Basic implementation as can be seen by the Spectrum results.

Results

The results are listed below and for each the higher the number the faster they are.

Machine Basic Printing Functions Strings For Loops Gosubs Arrays Maths Average
Atari ST ST Basic 243 177 96 53 363 269 119 189
Amstrad CPC6128 Locomotive Basic 143 29 164 39 384 193 53 144
Amstrad PCW 9256 Mallard Basic 251 26 140 43 314 173 53 143
Spectrum +3 Mallard Basic 145 26 136 42 306 167 52 125
C128c1 Basic 7.0 305 22 86 32 108 141 35 104
Amstrad PCW 9256 Basic-80 (MBasic) 214 19 89 21 240 104 31 103
C128c2 Basic 7.0 292 22 82 30 93 137 35 99
Vic-20 Basic 2 267 14 109 28 140 115 25 98
Spectrum +3 Basic-80 (MBasic) 117 18 86 20 235 101 30 87
C64 Basic 2 222 12 92 24 117 97 21 84
Pet 8032 Basic 4.0 249 12 86 24 86 98 22 82
MFA Mikrocomputerm1 Basic-80 (MBasic) 186 14 64 15 167 77 23 78
Sinclair QL SuperBasic 112 43 68 16 93 98 77 72
Plus/4 Basic 3.5 180 14 53 18 70 83 22 63
C128c4 Basic 7.0 144 11 41 16 52 68 17 50
C128c3 Basic 7.0 148 11 40 15 45 66 17 49
C128c5 Basic-80 (MBasic) 99 9 42 9 101 52 15 47
Spectrum 48k 48 Basic 88 6 28 5 27 42 17 30
Spectrum +3 +3 Basic 69 6 24 4 23 34 16 25

Notes

c1 Basic 7.0, 80 column, fast mode, running commodore/bench.bas version
c2 Basic 7.0, 80 column, fast mode, running C128 windowed version: commodore/bench_c128.bas
c3 Basic 7.0, 80 column, slow mode, running C128 windowed version: commodore/bench_c128.bas
c4 Basic 7.0, 40 column, slow mode, running commodore/bench.bas version
c5 CP/M 80 column, running cpm/mbasic.bas
m1 2Mhz 8085 machine - Thanks to Robert

Observations

The benchmarks for a few of the machines stand out for me because they were unexpected or confirmed what I had already heard.

Sinclair QL

The biggest surprise for me was how slow the Sinclair QL was. I knew it was hampered by the choice of a Motorola 68008, instead of a 68000, but the benchmark indicates just what a difference this decision made. It is particularly apparent if you consider the Amstrad PCW and Amstrad CPC6128 which were aimed at or could appeal to a similar market and deliver the sorts of speed that the QL should have delivered even if they had just stuck with the z80. That said, when it comes to the Functions and Maths test it was ahead of all the 8-bit machines and it would have been much easier to make use of the extra memory it could address without having to resort to bank switching.

Commodore 128

It is often said how slow CP/M was on the C128 and if you compare the benchmarks for the C128 vs the Amstrad PCW using Basic-80, it is quite clear just how slow it was. I'm also struck by how much slower the C128 was using Basic 7.0 in slow mode than the C64 using Basic 2. It would be interesting to know why this is.

Atari ST

The benchmark for ST Basic, while being top of the list, probably says more about the poor implementation of Basic than it does about the Hardware itself.

Sinclair Spectrum

This really underlines what a difference the implementation of Basic makes. If you take the Spectrum +3 running +3 Basic compared to when it is running Mallard Basic under CP/M; the Mallard Basic version runs about 5 times as quickly on the same hardware.

Emulators

All the tests have been run on emulators as I don't have all the machines and it makes the tests easy to reproduce. They all aim to be cycle accurate, but naturally they have to allow some flexibility otherwise they would be too resource intensive. Therefore the benchmark figures will never be quite as accurate as running on real hardware, but should give a good indication of their speed.

EmulatorMachines
Arnold Amstrad: CPC6128
Fuse Sinclair: Spectrum 48k, Spectrum +3
Hatari Atari: ST
JOYCE Amstrad: PCW
Q-emuLator Sinclair: QL
Vice Commodore: Pet, Vic-20, C64, C128, Plus/4

The Basic Code

I have put the Commodore Basic version below as I think it is the simplest version to understand. In the code the variable ti holds the value of the system clock and is updated every 1/60th of a second. The Basic source code for all versions are held in the GitHub repo.

10 rem basic benchmark
20 rem inspired by qsbb from qlay sinclair ql emulator
30 rem
40 rem copyright (c) 2019 lawrence woodman
50 rem licensed under an mit licence

100 rem array used later
110 dim ar(20)

200 print "basic benchmark"
210 print "7 tests, 20 seconds each"
220 print

1000 rem calculate benchmarks
1010 print
1020 print "please wait..."
1030 print

1100 rem benchmark printing
1110 t=ti
1120 p=0
1130 for i=1 to 20
1140 print ".";
1150 next i
1160 p=p+1
1170 if ti-t<=1200 then goto 1130

1300 rem benchmark functions
1310 t=ti
1320 f=0
1330 for i=1 to 20
1340 ra=sin(0.1):rb=log(4):rc=exp(10)
1350 next i
1360 f=f+1
1370 if ti-t<=1200 then goto 1330

1500 rem benchmark strings
1510 t=ti
1520 s=0
1530 for i=1 to 20
1540 a$="abcdefghijklmnopqrstuvwxyz"
1550 b$="zyxwvutsrqponmlkjihgfedcba"
1560 c$=a$+b$
1570 next i
1580 s=s+1
1590 if ti-t<=1200 then goto 1530

1700 rem benchmark for loops
1710 t=ti
1720 l=0
1730 for i=1 to 20
1740 for j=1 to 20: next j
1750 next i
1760 l=l+1
1770 if ti-t<=1200 then goto 1730

1800 rem benchmark gosubs
1810 goto 1830
1820 return
1830 t=ti
1840 g=0
1850 for i=1 to 20
1860 gosub 1820:gosub 1910
1870 next i
1880 g=g+1
1890 if ti-t<=1200 then goto 1850
1900 goto 1920
1910 return
1920 :

2000 rem benchmark arrays
2010 t=ti
2020 a=0
2030 for i=1 to 20
2040 ar(i)=i:b=ar(i)
2050 next i
2060 a=a+1
2070 if ti-t<=1200 then goto 2030


2200 rem benchmark maths
2210 t=ti
2220 m=0
2230 ka=5
2240 kb=6.2
2250 for i=1 to 20
2260 r=ka+kb-ka/kb*ka*kb
2270 r=5+6.2-5/6.2*5*6.2
2280 next i
2290 m=m+1
2300 if ti-t<=1200 then goto 2250

3010 print:print
3020 print "results"
3030 print "======="
3040 print "printing:  "; p
3050 print "functions: "; f
3060 print "strings:   "; s
3070 print "for loops: "; l
3080 print "gosubs:    "; g
3090 print "arrays:    "; a
3100 print "maths:     "; m
Creative Commons License
Benchmarking Basic on Vintage Computers by Lawrence Woodman is licensed under a Creative Commons Attribution 4.0 International License.

Share This Post

Feedback/Discuss

Related Articles

Getting the Address of BASIC Variables on the VIC-20

Getting the address of a BASIC variable can be useful if you want to pass data to a machine code routine or want to access the bytes of a variable directly to improve speed and reduce garbage collectio...   Read More

Saving and Loading Memory on the VIC-20

Saving and loading memory is quite easy on the VIC-20 once you know how. However, it isn't obvious how to do this and therefore this article will present a few simple ways of doing it from BASIC and A...   Read More

Basic Line Storage on the VIC-20

BASIC programs are stored in memory using a simple structure that we can investigate and manipulate. This article will show how they are stored and contains a BASIC program to go through each line of ...   Read More

Storing Machine Code in REM Statements on the VIC-20

BASIC programs often contain machine code routines but they take up quite a lot of space in BASIC. An interesting way to reduce the amount of space that they take is to store the machine code in REM s...   Read More

Adding Basic Stubs to Assembly Language on the Commodore VIC-20

To make machine language programs more friendly it's nice to add a Basic stub which contains a line with a SYS statement to start the code. This is easy to do on the VIC-20 and the process gives you a...   Read More