The ultimate Forth Benchmark

1 About

The Ultimate Benchmark is a competition held during retro computing events. The goal of this competition is not to find the fasted and most capable machine or Forth system, but to price the most active participant.

The Ultimate Benchmark started years ago during an discussion over beer at one VCFe ( http://vcfe.org ) between Hans, Dino and Carsten over wether a 6502 Forth with 1.79 Mhz (Atari 8bit) will be faster or slower than a Z80 Forth at 4 Mhz. It was benchmarked the other day, Z80 won. But we've got hooked and started benchmarking other machines, and Hans turned it into an yearly competition at VCFe in Munich. It is always fun.

If you are new to Forth, don't fear, there are plenty of Forth people around that are eager to help.

The benchmark competition has two goals:

  • provide motivation for the people at VCFe / VCFb (or other Retro meetings) to do some "practical" work on their machine while having the systems on display
  • have fun with the machines

Being precise, accurate or producing meaningful benchmark results is actually not the goal :)

The main goal is: try to get the best possible result while still having fun!

2 Forth-Systems

This sub-page lists a list of new and old Forth systems for various CPU architectures and Computer systems. Forth is possibly the most ported computer language available: Forth-Systems.

3 Rules

  • any Forth permitted
  • any Machine (Retro machines 15 years and older are preferred)
  • each participant can enter a submission for each combination of Forth-System and Machine with at least three (3) of the Benchmarks below
  • The winner will be drawn at the end of the event out of all submissions
  • the more combinations of Forth systems and retro machines one participant has submitted, the greater is the statistical chance to win

4 Forth83 Benchmarks

Below is a collection of some Benchmarks for Forth83 systems like VolksForth.

I found most of these benchmarks on

Some benchmarks might need adjustment on machines with a stack-cell size > 16 bit, see notes at the benchmark sources.

5 Results VCFB 2022

Name System Forth Benchmark Time (sec/round) Year
Stefan Koch KC 85/4 U880D 1.77Mhz KC-Forth DDBench 1m 32s (1) 2022
Stefan Koch KC 85/4 U880D 1.77Mhz KC-Forth FIB2 3m 08s (1000) 2022
Stefan Koch KC 85/4 U880D 1.77Mhz KC-Forth Deliano 39s (1) 2022
Martin Wend Space Age2 MIPS1 pForth DDBench 1m 24s (20) 2022
Martin Wend Space Age2 MIPS1 pForth Integer 13s (1) 2022
Martin Wend Space Age2 MIPS1 pForth MemMove 24s (1) 2022
Jürgen Weigert Sparc Station LX MicroSparc 1 50Mhz OpenBoot DDBench 3s (100) 2022
Jürgen Weigert Sparc Station LX MicroSparc 1 50Mhz OpenBoot Deliano 21s (1) 2022
Jürgen Weigert Sparc Station LX MicroSparc 1 50Mhz OpenBoot GCD1 1m 10s (100) 2022
Perry Melange TI 99/L-A TMS9900 3Mhz TurboForth 1.2.2 DDBench 1m 19s (20) 2022
Perry Melange TI 99/L-A TMS9900 3Mhz TurboForth 1.2.2 Integer 2m 01s (10) 2022
Perry Melange TI 99/L-A TMS9900 3Mhz TurboForth 1.2.2 MemMove 3m 28s (10) 2022

6 Results VCFB (online) 2020

Name System Forth Benchmark Time (sec/round) Year
Carsten Strotmann Atari 260ST 32Forth Deliano 1000x 30s 2020
Carsten Strotmann Atari 260ST 32Forth Integer 1x 8s 2020
Carsten Strotmann Atari 260ST 32Forth Nesting 1mil 42s 2020
Carsten Strotmann Atari 260ST 32Forth BitsInBytes 9s 2020
Carsten Strotmann Atari 260ST 32Forth GCD2 21s 2020
Carsten Strotmann Atari 260ST 32Forth GCD3 23s 2020
Carsten Strotmann Atari 260ST 32Forth DUP-DROP 100x 2m 04s 2020
Carsten Strotmann Atari 260ST 32Forth Mem-Move 10x 42s 2020
Carsten Strotmann Atari 260ST F68Kans Deliano 10x 21s 2020
Carsten Strotmann Atari 260ST F68Kans Integer 10x 18s 2020
Carsten Strotmann Atari 260ST F68Kans DUP-DROP 100x 39s 2020
Carsten Strotmann Atari 260ST OneForth BitInBytes 7s 2020
Carsten Strotmann Atari 260ST OneForth Integer 10x 26s 2020
Carsten Strotmann Atari 260ST OneForth Deliano 10x 1m 30s 2020
Carsten Strotmann Atari 260ST OneForth DUP-DROP 100x 1m 10s 2020
Carsten Strotmann Atari 260ST OneForth Nesting 1mil 38s 2020
Carsten Strotmann Atari 260ST OneForth GCD2 15s 2020
Carsten Strotmann Atari 260ST OneForth GCD3 4s 2020
Carsten Strotmann Atari 260ST OneForth Mem-Move 10x 60s 2020
           

7 Results DoReCo Treffen

Name System Forth Benchmark Time (sec/round) Year
Carsten Fulde Sinclair QL M68008 7,5 Mhz Forth79 (G.W.Jackson) GCD 1 21 2019
Carsten Fulde Sinclair QL M68008 7,5 Mhz Forth79 (G.W.Jackson) Integer Calc 4.4 2019
Carsten Fulde Sinclair QL M68008 7,5 Mhz Forth79 (G.W.Jackson) Fibonacci 2 35 2019
Carsten Strotmann Nixdorf 8810 M15 (8Mhz i286) L.O.V.E. Forth GCD 1 6 2019
Carsten Strotmann Nixdorf 8810 M15 (8Mhz i286) L.O.V.E. Forth Integer Calc 0.8 2019
Carsten Strotmann Nixdorf 8810 M15 (8Mhz i286) L.O.V.E. Forth Fibonicci 2 8 2019

8 Results VCFe

Name System Forth Benchmark Time (sec/round) Year
Enrico/Dirk Robotron A 7150 i8086/8087 Multibus ~5Mhz VolksForth MS-DOS (ITC) Fibonacci 2 46 2017
Enrico/Dirk Robotron A 7150 i8086/8087 Multibus ~5Mhz VolksForth MS-DOS (ITC) MemMove 8 2017
Enrico/Dirk Robotron A 7150 i8086/8087 Multibus ~5Mhz VolksForth MS-DOS (ITC) GCD 1 25 2017
Enrico/Dirk Robotron A 7150 i8086/8087 Multibus ~5Mhz VolksForth MS-DOS (ITC) GCD 2 30 2017
Ralf Neumann Yodabashi Formula 1 Z80 4Mhz VolksForth CP/M (ITC) GCD 1 42 2017
Ralf Neumann Yodabashi Formula 1 Z80 4Mhz VolksForth CP/M (ITC) Takeuchi 46 2017
Ralf Neumann Yodabashi Formula 1 Z80 4Mhz VolksForth CP/M (ITC) MemMove 24 2017
Carsten Strotmann Scheider Tower AT 220 i286 10Mhz VolksForth MS-DOS (ITC) MemMove 8 (10x) 2017
Carsten Strotmann Scheider Tower AT 220 i286 10Mhz VolksForth MS-DOS (ITC) GCD 1 5 2017
Carsten Strotmann Scheider Tower AT 220 i286 10Mhz VolksForth MS-DOS (ITC) Fibonacci2 8 2017
Carsten Strotmann Amstrad NC100 Z80 4.606Mhz VolksForth CP/M (ITC) Integer Calc 6.23  
Carsten Strotmann Atari Portfolio 8088 4.92Mhz VolksForth MS-DOS (ITC) Integer Calc 4.96  
Martin Metz Amstrad NC100 Z80 4.606Mhz VolksForth CP/M (ITC) GCD 1 38.1  
Andreas Boehm Commodore C64 6510 Audiogenic Forth-64 Integer Calc 526  
Andreas Boehm Commodore C64 6510 Audiogenic Forth-64 Count Bits 140.22  
Andreas Boehm Commodore C64 6510 Audiogenic Forth-64 Sieve Bench 18.1  
Andreas Boehm Commodore C64 6510 Audiogenic Forth-64 GCD 1 215.52  
Andreas Boehm Commodore C64 6510 Audiogenic Forth-64 GCD 2 84.84  
H. Jakob c't 86 8086 5Mhz Laxen/Perry F83 Integer Calc 9  
Neil Franklin HP 100LX 80186 7.9Mhz VolksForth 3.81.41 MS-DOS Integer Calc 2.8  
Carsten Strotmann Atari 130XE 6502 1.79Mhz VolksForth 3.81 Integer Calc 596  
Carsten Strotmann Atari 130XE 6502 1.79Mhz noDMA VolksForth 3.81 Integer Calc 438  
J. Kunz DEC 3000-600 Alpha 21064 175Mhz pForth Integer Calc 0.091  
J. Kunz DEC 3000-600 Alpha 21064 175Mhz pForth Fibonacci 1 0.0038  
J. Kunz DEC 3000-600 Alpha 21064 175Mhz pForth Fibonacci 2 0.00001425  
J. Kunz DEC 3000-600 Alpha 21064 175Mhz pForth Nesting 32Mil 22  
J. Kunz DEC 3000-600 Alpha 21064 175Mhz pForth 6502emu 18  
Ingo Soetebier Nextstation 68040 33Mhz pfe Nesting 1Mil 340  
KC85 Team KC85/4 U880 4Mhz VolksForth CP/M Nesting 1Mil 144  
Venty Thinkpad T61, 2Ghz Core Duo gforth-fast, Linux Integer Calc 0.0013  
Venty Thinkpad T61, 2Ghz Core Duo gforth, Linux Integer Calc 0.0019  
Venty Nokia N900 ARM A8 600Mhz gforth-fast, Linux Nesting 32Mil 3.9  
Venty Nokia N900 ARM A8 600Mhz gforth-fast, Linux Sieve Bench 0.015  
Venty Nokia N900 ARM A8 600Mhz gforth-fast, Linux 6502emu 1  
Venty Nokia N900 ARM A8 600Mhz gforth-dtc, Linux Nesting 32Mil 5.5  
Venty Nokia N900 ARM A8 600Mhz gforth-dtc, Linux Sieve Bench 0.025  
Venty Nokia N900 ARM A8 600Mhz gforth-dtc, Linux 6502emu 1.8  
Venty Nokia N900 ARM A8 600Mhz gforth-itc, Linux Nesting 32Mil 6.9  
Venty Nokia N900 ARM A8 600Mhz gforth-itc, Linux Sieve Bench 0.028  
Venty Nokia N900 ARM A8 600Mhz gforth-itc, Linux 6502emu 2.2  
Thorsten Kuphaldt Amiga 3000 68030 25Mhz jforth Integer Bench 0.24  
Thorsten Kuphaldt Amiga 3000 68030 25Mhz jforth Nesting 1Mil 1.32  
Thorsten Kuphaldt Amiga 3000 68030 25Mhz jforth Memory Move 0.67  
Thorsten Kuphaldt Amiga 3000 68030 25Mhz jforth Sieve Bench 0.148  
Thorsten Kuphaldt Amiga 3000 68030 25Mhz jforth GCD 1 0.64  
Stefan Herold Amstrad 6128+ Z80A 4Mhz Uniforth Integer Calc 17  
Stefan Herold Amstrad 6128+ Z80A 4Mhz Uniforth Fibonacci 2 0.23  
Stefan Herold Amstrad 6128+ Z80A 4Mhz Uniforth Nesting 1Mil 206  
Stefan Herold Amstrad 6128+ Z80A 4Mhz Uniforth Sieve Bench 12  
Ingo Soetebier iBook PPC 750lx (G3) 600Mhz OpenFirmware Integer Calc 0.03  
Ingo Soetebier iBook PPC 750lx (G3) 600Mhz OpenFirmware Fibonacci 1 0.0026  
Ingo Soetebier iBook PPC 750lx (G3) 600Mhz OpenFirmware Fibonacci 2 0.0027  
Ingo Soetebier iBook PPC 750lx (G3) 600Mhz OpenFirmware Nesting 1Mil 1  
Ingo Soetebier iBook PPC 750lx (G3) 600Mhz OpenFirmware Sieve Bench 0.031  
Ingo Soetebier iBook PPC 750lx (G3) 600Mhz OpenFirmware GCD 1 0.024  
Michael Kalus Rockwell R1200-14, 2Mhz 65F12 RSC-Forth Fibonacci 1 16.09  
Michael Kalus Rockwell R1200-14, 2Mhz 65F12 RSC-Forth Fibonacci 2 0.05  
Michael Kalus Rockwell R1200-14, 2Mhz 65F12 RSC-Forth Nesting 1Mil 149  
Michael Kalus Rockwell R1200-14, 2Mhz 65F12 RSC-Forth Integer Calc 31  
Matthias Trute Atmega16 8MHz amForth 4.4 Integer Calc 1.56  
Matthias Trute Atmega16 8MHz amForth 4.4 Fibonacci 1 1.46  
Matthias Trute Atmega16 8MHz amForth 4.4 Fibonacci 2 0.0047  
Matthias Trute Atmega16 8MHz amForth 4.4 Nesting 1Mil 15.4  
Matthias Trute Atmega16 8MHz amForth 4.4 Nesting 32Mil 489  
Matthias Trute Atmega16 8MHz amForth 4.4 GCD 1 7.12  
Matthias Trute Atmega16 8MHz amForth 4.4 GCD 2 10.5  
Matthias Trute Atmega16 8MHz amForth 4.4 Takeuchi 0.7  
Michael Kalus MSP430FR5739, 8Mhz DCO intern MSP-EXP430FR5739 Experimenter Board CamelForth Integer Calc 100x 02'45':10  
Michael Kalus MSP430FR5739, 8Mhz DCO intern MSP-EXP430FR5739 Experimenter Board CamelForth FIB1 100x 00'46':39  
Michael Kalus MSP430FR5739, 8Mhz DCO intern MSP-EXP430FR5739 Experimenter Board CamelForth FIB2 10000x 00'16':91  
Michael Kalus MSP430FR5739, 8Mhz DCO intern MSP-EXP430FR5739 Experimenter Board CamelForth Nesting 32Mil 02'31':23  
Carsten Strotmann IBM L40S (386SX) mina (Fig-Forth) Fib2 (1000) 8s  
Carsten Strotmann IBM L40X (386SX) F83 (Laxen & Perry) Fib2 (1000) 8s  
Carsten Strotmann IBM L40X (386SX) GNU Forth 0.5.0 ec8086 Fib2 (1000) 24s  
Carsten Strotmann IBM L40X (386SX) VolksForth MS-DOS Fibonacci 1 0.36s  
Thorsten Schoeler Sinclair Spectrum+ Aber Forth (FIG-Forth) Integer 25s  
Thorsten Schoeler " " prime 11s  
Thorsten Schoeler " " Nesting 1m 3m17s  
Thorsten Schoeler " " GCD1 2m14s  
Thorsten Schoeler " " Fib2 (1000) 1m46s  
Thorsten Schoeler HX-20 Epson Forth E1.0 Fib2 (1000) 3m16s  
Thorsten Schoeler HX-20 " Nesting 32mil 2h43m49s  
Thorsten Schoeler HX-20 " Nesting 1mil 5m08s  
Thorsten Schoeler HX-20 " Integer 32tsd 1m03s  
Thorsten Schoeler HX-20 6301 614khz " Prime 23s  
Thorsten Schoeler ZX Spectrum 2+ FIG-Forth 1.1a Nesting 3m15s  
Thorsten Schoeler ZX Spectrum 2+ " MemMove 10s  
Thorsten Schoeler ZX Spectrum 2+ Spect ZX Forth 1.1 Nesting 4m13s  
Thorsten Schoeler ZX Spectrum 2+ " MemMove 28s  
Wolfgang Stief SUN SparcStation 10 TI TMS390255 OpenFirmware Integer 0,14s  
Wolfgang Stief SUN SparcStation 10 TI TMS390255 OpenFirmware Fib1 0,005s  
Wolfgang Stief SUN SparcStation 10 TI TMS390255 OpenFirmware Fib2 0,2s  
Wolfgang Stief SUN SparcStation 10 TI TMS390255 OpenFirmware Memory Move 143s  
Wolfgang Stief SUN SparcStation 10 TI TMS390255 OpenFirmware Prime 0,11s  
Wolfgang Stief SUN SparcStation 10 TI TMS390255 OpenFirmware GCD1 0,51s  
Wolfgang Stief SUN SparcStation 10 TI TMS390255 OpenFirmware GCD2 0,65s  
Wolfgang Stief SUN SparcStation 10 TI TMS390255 OpenFirmware Takeuchi 0,06s  
Wolfgang Stief SUN Ultra 1 200 Mhz UltraSprac OpenBoot 3.25 Integer 0,33s  
Wolfgang Stief SUN Ultra 1 200 Mhz UltraSprac OpenBoot 3.25 Fib1 0,014s  
Wolfgang Stief SUN Ultra 1 200 Mhz UltraSprac OpenBoot 3.25 Fib2 0,06s  
Wolfgang Stief SUN Ultra 1 200 Mhz UltraSprac OpenBoot 3.25 Nesting 32mil 9s  
Wolfgang Stief SUN Ultra 1 200 Mhz UltraSprac OpenBoot 3.25 Mempry Move 0,014s  
Wolfgang Stief SUN Ultra 1 200 Mhz UltraSprac OpenBoot 3.25 Prime 0,03s  
Wolfgang Stief SUN Ultra 1 200 Mhz UltraSprac OpenBoot 3.25 GCD1 0,08s  
Wolfgang Stief SUN Ultra 1 200 Mhz UltraSprac OpenBoot 3.25 GCD2 0,11s  
Wolfgang Stief SUN Ultra 1 200 Mhz UltraSprac OpenBoot 3.25 Takeuchi 0,009s  
Thorsten Schoeler Fignition (ATMEL) Fignition Forth fib2 (1000) 13s  
Stefan Niestegge Atari Falcom 68060 100mhz f68kans Integer 0,022s  
Stefan Niestegge Atari Falcon 68060 100mhz f68kans Fib2 0,0012s  
Stefan Niestegge Atari Falcon 68060 f68kans Countbits 0,05s  
Stefan Niestegge Atari Falcon 68060 f68kans GCD1 0,063s  
Stefan Niestegge Atari Falcon 68060 f68kans GCD2 0,067s  
Stefan Niestegge Atari Falcon 68060 f68kans Nesting 32mil 7,4s  
Thorsten Kuphaldt C64 (normal) Forth64 Nesting 1mill 6m20  
" C64 (Turbo FPGA 6502) Forth64 Nesting 1mill 25s  
" C64 (normal) Forth64 Fib2 (1000) 3m50s  
" C64 (Turbo FPGA 6502) Forth64 Fib2 (1000) 16s  
Martin Neitzel Asus EeePC 1000h (Atom N270 1.6Ghz) FreeBSD 9 FICL Bootloader Integer 0,00075s  
Martin Neitzel Asus EeePC 1000h (Atom N270 1.6Ghz) FreeBSD 9 FICL Bootloader Fib2 66s  
Martin Neitzel Asus EeePC 1000h (Atom N270 1.6Ghz) FreeBSD 9 FICL Bootloader Nesting 1mil 0.66s  
Martin Neitzel Asus EeePC 1000h (Atom N270 1.6Ghz) FreeBSD 9 FICL Bootloader Nesting 32mil 21s  
Martin Neitzel Asus EeePC 1000h (Atom N270 1.6Ghz) FreeBSD 9 FICL Bootloader GCD2 0.57s  
Sabine "Atari Frosch" Engelhardt Atari Portfolio VolksForth 3.81 Fib2 35s  
Sabine "Atari Frosch" Engelhardt Atari Portfolio VolksForth 3.81 Prime 6s  
Sabine "Atari Frosch" Engelhardt Atari Portfolio VolksForth 3.81 Takeuchi 17s  
Herbert Lange Compaq Deskpro P166 pForth V27 Integer Calc 0,052s  
Herbert Lange Compaq Deskpro P166 pForth V27 Fib1 0,061s  
Herbert Lange Compaq Deskpro P166 pForth V27 Fib2 0,001s  
Herbert Lange Compaq Deskpro P166 pForth V27 Nesting 32mil 15,42s  
Herbert Lange Compaq Deskpro P166 pForth V27 Memory Move 0,124s  
Herbert Lange Compaq Deskpro P166 pForth V27 Prime 0,007s  
Herbert Lange Compaq Deskpro P166 pForth V27 GCD1 0,002s  
Herbert Lange Apple iMac G3 400Mhz pForth V27 Integer Calc 0,013s  
Herbert Lange Apple iMac G3 400Mhz pForth V27 Fib1 0,015s  
Herbert Lange Apple iMac G3 400Mhz pForth V27 Fib2 0,001s  
Herbert Lange Apple iMac G3 400Mhz pForth V27 Nesting 32mil 4,335s  
Herbert Lange Apple iMac G3 400Mhz pForth V27 Memory Move 0,028s  
Herbert Lange Apple iMac G3 400Mhz pForth V27 Prime 0,017s  
Herbert Lange Apple iMac G3 400Mhz pForth V27 GCD1 0,063s  
Herbert Lange DEC 3000 400s pForth V27 Integer 0,123s  
Herbert Lange DEC 3000 400s pForth V27 Fib1 0,098s  
Herbert Lange DEC 3000 400s pForth V27 Fib21 0,001s  
Herbert Lange DEC 3000 400s pForth V27 Nesting 32mil 30,694s  
Herbert Lange DEC 3000 400s pForth V27 Memory Move 0,207s  
Herbert Lange DEC 3000 400s pForth V27 Prime 0,117s  
Herbert Lange DEC 3000 400s pForth V27 GCD1 0,483  
Herbert Lange SUN Ultra 1 Creator 3D pForth V27 Integer 0,049s  
Herbert Lange SUN Ultra 1 Creator 3D pForth V27 Fib1 0,052s  
Herbert Lange SUN Ultra 1 Creator 3D pForth V27 Fib2 0,001s  
Herbert Lange SUN Ultra 1 Creator 3D pForth V27 Nesting 32mil 15,631s  
Herbert Lange SUN Ultra 1 Creator 3D pForth V27 Memory Move 0,093s  
Herbert Lange SUN Ultra 1 Creator 3D pForth V27 Prime 0,060s  
Herbert Lange SUN Ultra 1 Creator 3D pForth V27 GCD1 0,022s  
Ralf Neumann mc-CP/M Z80 4Mhz FIG-Forth 1.1 Fib2 1m19s  
Ralf Neumann Prof80 CP/M Z80 6Mhz FIG-Forth 1.1 Fib2 53s  
Carsten Strotmann Zilog Super-8 20Mhz Super8 Forth Fib2 (1000) 31s  
Carsten Strotmann Zilog Super-8 20Mhz Super8 Forth Nesting 1m 20s  
Carsten Strotmann Zilog Super-8 20Mhz Super8 Forth Nesting 32m 11m02s  
Bernd Paysan Samsung Galaxy Note 2 (Exynos 4core) Gforth Fib2 (1000) 0.01s  
Thorsten Schoeler PDP11 FIG-Forth 1.3 Fib2 (1000) 37s  
Thorsten Schoeler PDP11 FIG-Forth 1.3 Fib1 (25) 36s  
Thorsten Schoeler PDP11 FIG-Forth 1.3 Nesting 1m 49s  
Norbert Kehrer Mupid II (BTX Decoder) FIG-Forth 1.1 Fib2 (1000) 210s  
Norbert Kehrer Mupid II (BTX Decoder) FIG-Forth 1.1 Nesting 1m 380s  
Norbert Kehrer Mupid II (BTX Decoder) FIG-Forth 1.1 Sieve 22s  
Norbert Kehrer Mupid II (BTX Decoder) FIG-Forth 1.1 GCD 1 205s  
Norbert Kehrer Mupid II (BTX Decoder) FIG-Forth 1.1 GCD 2 188s  
Thorsten Schoeler NCR 3150 486SX/25Mhz+FPU=Linux 2.0.0 gforth 0.3.0 Fib2 (2500) 9.2s  
Thorsten Schoeler NCR 3150 486SX/25Mhz+FPU=Linux 2.0.0 gforth 0.3.0 Nesting 1m 3s  
Thorsten Schoeler NCR 3150 486SX/25Mhz+FPU=Linux 2.0.0 gforth 0.3.0 Nesting 32m 1m35s  
Thorsten Schoeler NCR 3150 486SX/25Mhz+FPU=Linux 2.0.0 gforth 0.3.0 Fib1 1m79s  
Norbert Kehrer Mupid II (BTX Decoder) Camel Forth 1.01 Integer 68s  
Norbert Kehrer Mupid II (BTX Decoder) Camel Forth 1.01 Fib 2 (1000) 150s  
Norbert Kehrer Mupid II (BTX Decoder) Camel Forth 1.01 Nesting 1m 292s  
Norbert Kehrer Mupid II (BTX Decoder) Camel Forth 1.01 Sieve 15s  
Norbert Kehrer Mupid II (BTX Decoder) Camel Forth 1.01 GCD 1 116s  
Norbert Kehrer Mupid II (BTX Decoder) Camel Forth 1.01 GCD 2 135s  
Helfried Schuerer robotron K 1510, U 808 D (i8008), 480 kHz (auf FOSY Emulator) FOSY V1.2P 1988 (FIG) 1000 FIB2 00:00:15 15s  
Helfried Schuerer robotron K 1510, U 808 D (i8008), 480 kHz (auf FOSY Emulator) FOSY V1.2P 1988 (FIG) FIB2-BENCH 01:51:58 1h 51min 58s  
Helfried Schuerer robotron K 1510, U 808 D (i8008), 480 kHz (auf FOSY Emulator) FOSY V1.2P 1988 (FIG) Nesting 1MILLION 02:32:05 2h 32min 5s  

9 Results VCFB October 2014:

Name Geraet Forth Benchmark Messung Skalierung
Ben IBM PS/2 L40SX DX-Forth Integer 1m12s 100x
Ben IBM PS/2 L40SX DX-Forth Fib2 1m03s 10x
Ben IBM PS/2 L40SX DX-Forth GCD1 0m29s 10x
Ben IBM PS/2 L40SX DX-Forth GCD2 0m42s 10x
Thunder.Bird Amstrad PPC 512 DX-Forth Integer 4m02s 10x
Thunder.Bird Amstrad PPC 512 DX-Forth Fib2 1m45s 5x
Thunder.Bird Amstrad PPC 512 DX-Forth GCD1 0m48s 5x
Alexander Muller IBM PS/2 L40SX DX-Forth fib2 1m03s 10x
Alexander Muller IBM PS/2 L40SX DX-Forth gcd1 0m15s 5x
Alexander Muller IBM PS/2 L40SX DX-Forth integer 0m07s 10x
Alexander Muller IBM PS/2 L40SX DX-Forth takeuchi 0m04s 100x
Alexander Muller Raspberry Pi ARM 700Mhz Gforth 0.7.0 gcd1 0m04s 100x
Alexander Muller Raspberry Pi ARM 700Mhz Gforth 0.7.0 Takeuchi 0m02s 5000x
Alexander Muller Raspberry Pi ARM 700Mhz Gforth 0.7.0 Sieve 0m08s 100x
Michael Mengel Apple II UltraWarp 13Mhz Apple II v. 3.2 Fib2 0m21s 1x
Michael Mengel Apple II UltraWarp 13Mhz Apple GraForth Fib2 0m11s 1x
Michael Mengel Apple II 1Mhz Apple II v. 3.2 Fib2 3m56s 1x
Michael Mengel Apple II 1Mhz Apple GraForth Fib2 2m19s 1x

10 other Results

Name Computer Forth Benchmark Result Scale
Johan Kotlinski C64 DurexForth 1.6.1 (STC) Integer 37s 1x
Johan Kotlinski C64 DurexForth 1.6.1 (STC) Fibonacci 2 1m57s 1x
Johan Kotlinski C64 DurexForth 1.6.1 (STC) Nest 1M 17s 1x
Johan Kotlinski C64 DurexForth 1.6.1 (STC) Sieve/Prime 10s 1x
Johan Kotlinski C64 DurexForth 1.6.1 (STC) GCD 1 60s 1x
Johan Kotlinski C64 DurexForth 1.6.1 (STC) GCD 2 70s 1x
Carsten Fulde Amiga 500 mit ACA1233n-Turbokarte (68030 @ 40 MHz) JForth 3.1 Delta Research (Phil Burk) GCD 1 0.4s 1x
Carsten Fulde Amiga 500 mit ACA1233n-Turbokarte (68030 @ 40 MHz) JForth 3.1 Delta Research (Phil Burk) Integer 0.087s 1x
Carsten Fulde Amiga 500 mit ACA1233n-Turbokarte (68030 @ 40 MHz) JForth 3.1 Delta Research (Phil Burk) Fibonacci 2 0.35s 1x
Carsten Fulde Enterprise 128 IS-Forth von B. Tanner Integer 23.3s 1x
Carsten Fulde Enterprise 128 IS-Forth von B. Tanner Fibonacci 2 118.4s 1x
Carsten Fulde Enterprise 128 IS-Forth von B. Tanner GCD 1 78s 1x
Carsten Strotmann A-ONE (Apple 1 Clone) mit 65C02 TaliForth 2 (STC) Fibonacci 2 1m50s 1x
Carsten Strotmann A-ONE (Apple 1 Clone) mit 65C02 TaliForth 2 (STC) Nest 1M 25s 1x
Carsten Strotmann A-ONE (Apple 1 Clone) mit 65C02 TaliForth 2 (STC) GCD 2 1m25s 1x
Carsten Strotmann A-ONE (Apple 1 Clone) mit 65C02 TaliForth 2 (STC) Deliano 29s 1x
Thomas Woinke Steckschwein 8MHz 65c02 TaliForth 2 (STC) Fibonacci 2 15.23s 1x
Thomas Woinke Steckschwein 8MHz 65c02 TaliForth 2 (STC) Next 1M 3.7s 1x
Thomas Woinke Steckschwein 8MHz 65c02 TaliForth 2 (STC) GCD 2 11.75s 1x
Thomas Woinke Steckschwein 8MHz 65c02 TaliForth 2 (STC) Deliano 4.16s 1x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 3 Mhz) Z79Forth 6502 13m15s 1x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 3 Mhz) Z79Forth bitsincell 8m20s 100x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 3 Mhz) Z79Forth bubble 4m31s 1x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 3 Mhz) Z79Forth collatz 5m51s 1x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 3 Mhz) Z79Forth deliano 7m53s 50x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 3 Mhz) Z79Forth fib1 52s 1x (24 fib1)
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 3 Mhz) Z79Forth dupdrop 6m03s 100x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 3 Mhz) Z79Forth fib2 11m55s 10x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 3 Mhz) Z79Forth gcd1 3m55.3s 10x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 3 Mhz) Z79Forth gcd2 4m59s 10x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 3 Mhz) Z79Forth gcd3 1m1s 10x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 3 Mhz) Z79Forth intcalc 6m44s 100x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 3 Mhz) Z79Forth memmove 7m00s 250x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 3 Mhz) Z79Forth nesting 1mil 0m49s 10x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 3 Mhz) Z79Forth nesting 32mil 2m37s 10x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 3 Mhz) Z79Forth qsort 4m46s 50x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 3 Mhz) Z79Forth sieve 3m45s ??x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 3 Mhz) Z79Forth takeuchi 0m55s 200x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 4 Mhz) Z79Forth 6502 9m56s 1x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 4 Mhz) Z79Forth bitsincell 6m15s 100x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 4 Mhz) Z79Forth bubble 3m24s 1x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 4 Mhz) Z79Forth collatz 4m23s 1x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 4 Mhz) Z79Forth deliano 5m55s 50x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 4 Mhz) Z79Forth fib1 39s 1x (24 fib1)
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 4 Mhz) Z79Forth dupdrop 4m32s 100x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 4 Mhz) Z79Forth fib2 8m57s 10x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 4 Mhz) Z79Forth gcd1 2m56.5s 10x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 4 Mhz) Z79Forth gcd2 3m44s 10x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 4 Mhz) Z79Forth gcd3 46s 10x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 4 Mhz) Z79Forth intcalc 5m02s 100x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 4 Mhz) Z79Forth memmove 5m15s 250x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 4 Mhz) Z79Forth nesting 1mil 0m37s 10x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 4 Mhz) Z79Forth nesting 32mil 1m57s 10x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 4 Mhz) Z79Forth qsort 3m34s 50x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 4 Mhz) Z79Forth sieve 2m49s ??x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 4 Mhz) Z79Forth takeuchi 0m33s 200x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 5 Mhz) Z79Forth 6502 7m57s 1x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 5 Mhz) Z79Forth bitsincell 5m 100x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 5 Mhz) Z79Forth bubble 2m43s 1x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 5 Mhz) Z79Forth collatz 3m30s 1x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 5 Mhz) Z79Forth deliano 4m44s 50x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 5 Mhz) Z79Forth fib1 31.5s 1x (24 fib1)
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 5 Mhz) Z79Forth dupdrop 3m38s 100x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 5 Mhz) Z79Forth fib2 7m09s 10x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 5 Mhz) Z79Forth gcd1 2m21s 10x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 5 Mhz) Z79Forth gcd2 2m59s 10x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 5 Mhz) Z79Forth gcd3 37s 10x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 5 Mhz) Z79Forth intcalc 4m02s 100x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 5 Mhz) Z79Forth memmove 4m12s 250x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 5 Mhz) Z79Forth nesting 1mil 0m29s 10x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 5 Mhz) Z79Forth nesting 32mil 1m34s 10x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 5 Mhz) Z79Forth qsort 2m52s 50x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 5 Mhz) Z79Forth sieve 2m15s ??x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 5 Mhz) Z79Forth takeuchi 0m33s 200x
Francois Laagel Z79Forth Reference Board (Hitachi HD63C09 5 Mhz) Z79Forth palindrome 3m42s 1x

11 TODO FIG-Forth Benchmark Versions

12 Forth 79 Benchmark Versions

Francois Laagel has ported the benchmark programs to the FORTH 79 standard.

12.1 Benchmark Helper

: BENCHME ( xt n -- )
  DUP >R 0 DO
    DUP EXECUTE
    [CHAR] . EMIT
  LOOP
  DROP R> SPACE . ." Iterations." SPACE ;

12.2 DUP-DROP

DECIMAL
: DDBENCH 1 32767 0 DO DUP DROP LOOP DROP ;
FIND DDBENCH 100 BENCHME

12.3 IntCalc (Integer Calculations)

DECIMAL
32000 CONSTANT INTMAX

VARIABLE INTRESULT

: DOINT 
  1 DUP INTRESULT DUP >R !
  BEGIN 
    DUP INTMAX <
  WHILE 
    DUP NEGATE R@ +! 1+
    DUP R@ +! 1+
    R@ @ OVER * R@ ! 1+
    R@ @ OVER / R@ ! 1+
  REPEAT
  R> DROP DROP ;

FIND DOINT 100 BENCHME

12.4 FIB1 (Fibonacci 1)

DECIMAL
: FIB2
  0 1 ROT 0 DO
    OVER + SWAP
  LOOP DROP ;

: FIB2-BENCH 1000 0 DO
    I FIB2 DROP
  LOOP ;

FIND FIB2-BENCH 10 BENCHME

12.5 FIB2 (Fibonacci 2)

DECIMAL
: FIB2
  0 1 ROT 0 DO
    OVER + SWAP
  LOOP DROP ;

: FIB2-BENCH 1000 0 DO
    I FIB2 DROP
  LOOP ;

FIND FIB2-BENCH 10 BENCHME

12.6 Nesting

DECIMAL
: BOTTOM ;
: 1ST BOTTOM BOTTOM ;  : 2ND 1ST 1ST ;      : 3RD 2ND 2ND ;
: 4TH 3RD 3RD ;        : 5TH 4TH 4TH ;      : 6TH 5TH 5TH ;
: 7TH 6TH 6TH ;        : 8TH 7TH 7TH ;      : 9TH 8TH 8TH ;
: 10TH 9TH 9TH ;       : 11TH 10TH 10TH ;   : 12TH 11TH 11TH ;
: 13TH 12TH 12TH ;     : 14TH 13TH 13TH ;   : 15TH 14TH 14TH ;
: 16TH 15TH 15TH ;     : 17TH 16TH 16TH ;   : 18TH 17TH 17TH ;
: 19TH 18TH 18TH ;     : 20TH 19TH 19TH ;   : 21TH 20TH 20TH ;
: 22TH 21TH 21TH ;     : 23TH 22TH 22TH ;   : 24TH 23TH 23TH ;
: 25TH 24TH 24TH ;
: 32MILLION   25TH ;
:  1MILLION   20TH ;
DECIMAL
FIND 1MILLION 10 BENCHME
FIND 32MILLION 10 BENCHME

12.7 Bubble (Bubble-Sort)

DECIMAL

: MYBOUNDS OVER + SWAP ;
: ALIGN ;              ( No such constraint on 16 bit targets )

1 CELLS CONSTANT CELL

VARIABLE SEED

: INITIATE-SEED ( -- )  4931 SEED ! ;
: RANDOM ( -- N )  SEED @ 613 * 5179 + 32767 AND DUP SEED ! ;

1500 CONSTANT ELEMENTS

ALIGN CREATE LIST ELEMENTS CELLS ALLOT

: INITIATE-LIST ( -- )
  LIST ELEMENTS CELLS + LIST DO
    RANDOM I ! CELL
  +LOOP ;

: VERIFY-LIST ( -- )
  LIST ELEMENTS 1- CELLS MYBOUNDS DO
    I 2@ < IF
      ." BUBBLE-SORT: not sorted" ABORT
    THEN
  CELL +LOOP ;

: BUBBLE-WITH-FLAG ( -- )
  ." Bubbling..." CR
  1 ELEMENTS 1 DO
    [CHAR] . EMIT
    -1 LIST ELEMENTS I - CELLS MYBOUNDS DO
      I 2@ < IF
        I 2@ SWAP I 2! DROP 0
      THEN
    CELL +LOOP 
    IF LEAVE THEN
  LOOP SPACE DROP ;
  
: BUBBLE-SORT-WITH-FLAG ( -- )
  INITIATE-SEED
  INITIATE-LIST
  BUBBLE-WITH-FLAG
  VERIFY-LIST ;

: DUMP-LIST ( -- )
  CR LIST ELEMENTS CELLS + LIST DO
    I @ 7 U.R SPACE CELL
  +LOOP CR ;

12.8 Quick-Sort

DECIMAL
1 CELLS CONSTANT CELL
: CELL+ CELL + ;
: CELL- CELL - ;

VARIABLE SEED
: INITIATE-SEED ( -- )  4931 SEED ! ;
: RANDOM ( -- N )  SEED @ 613 * 5179 + 32767 AND DUP SEED ! ;
1500 CONSTANT ELEMENTS
CREATE LIST ELEMENTS CELLS ALLOT

: INITIATE-LIST ( -- )
  LIST ELEMENTS CELLS + LIST DO
    RANDOM I ! CELL
  +LOOP ;

: DUMP-LIST ( -- )
  CR LIST ELEMENTS CELLS + LIST DO
    I @ 7 U.R SPACE CELL
  +LOOP CR ;

: MID ( l r -- mid ) OVER - 2/ CELL NEGATE AND + ;
: EXCH ( addr1 addr2 -- ) OVER @ OVER @
  SWAP ROT ! SWAP ! ;
: PARTITION ( l r -- l r r2 l2 )
  2DUP MID @ >R ( r: pivot )
  2DUP BEGIN
    SWAP BEGIN DUP @ R@ < WHILE CELL+ REPEAT
    SWAP BEGIN R@ OVER @ < WHILE CELL- REPEAT
    2DUP <= IF 2DUP EXCH >R CELL+ R> CELL- THEN
    2DUP >
  UNTIL R> DROP ;
 
: QSORT ( l r -- )
  PARTITION SWAP ROT
  2DUP < IF RECURSE ELSE 2DROP THEN
  2DUP < IF RECURSE ELSE 2DROP THEN ;
 
: QUICK-SORT ( -- )
  LIST ELEMENTS DUP 2 < IF
    2DROP EXIT
  THEN
  1- CELLS OVER + QSORT ;

: QUICK-SORT-BENCHMARK ( -- )
  INITIATE-SEED
  INITIATE-LIST
  QUICK-SORT
  ( DUMP-LIST ) ;

FIND QUICK-SORT-BENCHMARK 50 BENCHME

12.9 Bites-in-Bytes

HEX
( Adapted from "Hacker's Delight" Second Edition    )
( by Henry S. Warren Jr., Edt by Addison-Wesley     )
( Chapter 5 "Counting bits", page 82                )

: COUNTBITS ( uu -- #bits )
  DUP -1 SHIFT 5555 AND -
  DUP 3333 AND SWAP -2 SHIFT 3333 AND +
  DUP -4 SHIFT + 0F0F AND
  DUP -8 SHIFT +
  1F AND ;

DECIMAL
: BITSINCELL ( -- )
  8192 0 DO
    I COUNTBITS DROP
  LOOP ;

FIND BITSINCELL 100 BENCHME

12.10 Sieve

\ -------------------------------------------------------------
\ [BENCHMARK] Glibreath's fixed algorithm:
\ Eratosthenes' sieve from ORNL/TM10656 (Martin Marietta).

DECIMAL
8190 CONSTANT SIZE
VARIABLE FLAGS SIZE 1+ ALLOT

: DO-PRIME
  FLAGS SIZE 1+ 1 FILL
  0 SIZE 0 DO
    FLAGS I + C@ IF
      I DUP + 3 + DUP I +
      BEGIN
        DUP SIZE <=
      WHILE
        0 OVER FLAGS + C! OVER +
      REPEAT
      DROP DROP 1+
    THEN
  LOOP DROP ;

FIND DO-PRIME 50 BENCHME

12.11 Mem-Move

DECIMAL
8192 CONSTANT BUFSIZE
VARIABLE BUF1 HERE BUFSIZE 1+ ALLOT BUF1 !
VARIABLE BUF2 HERE BUFSIZE 1+ ALLOT BUF2 !
: TEST-CMOVE 50 0 DO BUF1 @ BUF2 @ BUFSIZE CMOVE LOOP ;
: TEST-CMOVE> 50 0 DO BUF2 @ BUF1 @ BUFSIZE CMOVE> LOOP ;
: TEST-MOVE> 50 0 DO
    BUF1 @ BUF2 @ BUFSIZE 1 CELLS / MOVE
  LOOP ;
: TEST-<MOVE 50 0 DO
    BUF2 @ BUF1 @ BUFSIZE 1 CELLS / MOVE
  LOOP ;
: MOVE-BENCH TEST-CMOVE TEST-CMOVE> TEST-MOVE> TEST-<MOVE ;

FIND MOVE-BENCH 250 BENCHME

12.12 GCD1

DECIMAL
: GCD1 OVER IF
    BEGIN
      DUP
    WHILE
      2DUP U> IF SWAP THEN OVER -
    REPEAT
    DROP
  ELSE
    DUP IF
      DROP
    ELSE
      2DROP 1
    THEN
  THEN ;

: GCD1-BENCH 100 0 DO
    100 0 DO
      J I GCD1 DROP
    LOOP
  LOOP ;

FIND GCD1-BENCH 10 BENCHME

12.13 GCD2

DECIMAL
: GCD2 ( a b -- gcd )
  2DUP     D0= IF 2DROP 1 EXIT THEN
  DUP      0=  IF  DROP   EXIT THEN
  SWAP DUP 0=  IF  DROP   EXIT THEN
  BEGIN
    2DUP -
  WHILE
    2DUP < IF
      OVER -
    ELSE
      SWAP OVER - SWAP
    THEN
  REPEAT NIP ;

: GCD2-BENCH 100 0 DO
    100 0 DO
      J I GCD2 DROP
    LOOP
  LOOP ;

FIND GCD2-BENCH 10 BENCHME

12.14 GCD3

\ -------------------------------------------------------------
\ GCD3 algorithm (provided by Paul E. Bennett).

DECIMAL
: GCD3 ( S: x y -- n) ( MCC=5 )
\ *G Find the Greatest Common Divisor "gcd" of two
\ ** integers "x and y", when at least one of them is
\ ** not zero. Return the largest positive integer "n"
\ ** that divides the two numbers without a remainder.
\ ** For example, the GCD of 8 and 12 is 4.
  2DUP <= IF
    SWAP
  THEN
  BEGIN
    TUCK MOD
    DUP 0=
  UNTIL DROP ;

: GCD3-BENCH 100 1 DO
    100 1 DO
      J I GCD3 DROP
    LOOP
  LOOP ;

FIND GCD3-BENCH 10 BENCHME

12.15 Deliano

HEX 
5 CONSTANT FIVE 
VARIABLE BVAR 

: BENCH 
  100 0 DO 
    1 BEGIN 
        DUP SWAP 
        DUP ROT DROP 
        1 AND IF 
          FIVE + 
        ELSE 
          1- 
        THEN 
        BVAR ! BVAR @ 
        DUP 0100 AND 
     UNTIL DROP 
   LOOP ;

DECIMAL
FIND BENCH 50 BENCHME

12.16 Collatz

( Collatz-Schritt. Null wenn Ueberlauf )
: cn+1 		( cn -- cm )
  2 /mod swap			
  if dup 10922 < 	( kein ueberlauf ? )
    if 3 * 2+ 
    else drop 0 then
  then
;
( Collatz-Folge drucken                         )
( dieses Wort wird im Benchmark nicht benoetigt )
( es druckt die Collatz-Folge aus               )
: coll. 	( cn -- )
  cr
  begin dup 1 > while
    cn+1 dup 8 u.r
  repeat
  drop		( always 1 )
;
( Collatz-Folge zaehlen. Null wenn Ueberlauf )
: ccnt 		( cn -- cnt)
  0 swap 	( cnt cn )
  begin dup 1 > while
  cn+1 dup 
	if swap 1+ swap ( zaehlen )
	else drop 0
	then
  repeat
  drop
;
( Maximum fuer alle Folgen bis k bestimmen )
: cmax 		( k -- max )
  0 swap	( max k )
  begin dup 0 > while
    dup ccnt 	( max k cnt )
    rot  	( k cnt max )
    max		( k max )
    swap	( max k )
    1-		( max k-1 )
  repeat
  drop
;
( Funktionstest, Ergebniss muss die Zahl "126" sein )
32101 cmax .

12.17 Takeuchi

\ -------------------------------------------------------------
\ Takeuchi algorithm
\ Adapted from FORTH-83 (PICK). NIP is ANSI (and builtin).

DECIMAL
: 3DUP 3 PICK 3 PICK 3 PICK ;
: TAK ( x y z -- t )
  OVER 4 PICK < NEGATE IF
    NIP NIP EXIT
  THEN
  3DUP ROT  1- -ROT RECURSE >R
  3DUP SWAP 1- -ROT SWAP RECURSE >R
            1- -ROT RECURSE
  R> SWAP R>   -ROT RECURSE ;

: TAKBENCH ( -- )
  0 1000 0 DO
    DROP 18 12 6 TAK
  LOOP
  DROP ;

FIND TAKBENCH 200 BENCHME

12.18 6502 Emulator

( A simple 6502 emulation benchmark                       cas )
( only 11 opcodes are implemented. The memory layout is:      )                   
(  2kB RAM at 0000-07FF, mirrored throughout 0800-7FFF        )
( 16kB ROM at 8000-BFFF, mirrored at C000                     )

DECIMAL
CREATE RAM 2048 ALLOT
: >RAM [ HEX ] 7FF  [ DECIMAL ] AND RAM + ;

CREATE ROM 16384 ALLOT
: >ROM [ HEX ] 3FFF [ DECIMAL ] AND ROM + ;

( 6502 registers                                              )
VARIABLE REG-A   VARIABLE REG-X   VARIABLE REG-Y
VARIABLE REG-S   VARIABLE REG-PC  : REG-PC+ REG-PC +! ;

( 6502 flags                                                  )
VARIABLE FLAG-C  VARIABLE FLAG-N  VARIABLE CYCLE
VARIABLE FLAG-Z  VARIABLE FLAG-V  : CYCLE+ CYCLE +! ;

HEX
: W@ DUP C@ SWAP 1+ C@ 100 * OR ;
: CS@ C@ DUP 80 AND IF 100 - THEN ;

: READ-BYTE ( address -- )
  DUP 8000 < IF >RAM C@ ELSE >ROM C@ THEN ;
: READ-WORD ( address -- )
  DUP 8000 < IF >RAM W@ ELSE >ROM W@ THEN ;
: DOJMP ( JMP aaaa )
  REG-PC @ >ROM W@ REG-PC ! 3 CYCLE+ ;
: DOLDA ( LDA aa )
  REG-PC @ >ROM C@ RAM + C@ DUP DUP REG-A !
  FLAG-Z ! 80 AND FLAG-N ! 1 REG-PC+ 3 CYCLE+ ;
: DOSTA ( STA aa )
  REG-A @ REG-PC @ >ROM C@ RAM + C! 1 REG-PC+ 3 CYCLE+ ;
: DOBEQ ( BEQ <aa )
  FLAG-Z @ 0= IF REG-PC @ >ROM CS@ 1+ REG-PC+ ELSE 1 REG-PC+
  THEN 3 CYCLE+ ;
: DOLDAI ( LDA #aa )
  REG-PC @ >ROM C@ DUP DUP REG-A ! FLAG-Z ! 80 AND FLAG-N !
  1 REG-PC+ 2 CYCLE+ ;
: DODEX ( DEX )
  REG-X @ 1- FF AND DUP DUP REG-X ! FLAG-Z ! 80 AND FLAG-N !
  2 CYCLE+ ;
: DODEY ( DEY )
  REG-Y @ 1- FF AND DUP DUP REG-Y ! FLAG-Z ! 80 AND FLAG-N !
  2 CYCLE+ ;
: DOINC ( INC aa )
  REG-PC @ >ROM C@ RAM + DUP C@ 1+ FF AND DUP ROT ROT SWAP C!
  DUP FLAG-Z ! 80 AND FLAG-N !  1 REG-PC+ 3 CYCLE+ ;
: DOLDY ( LDY aa )
  REG-PC @ >ROM C@ DUP DUP REG-Y ! FLAG-Z ! 80 AND FLAG-N !
  1 REG-PC+ 2 CYCLE+ ;
: DOLDX ( LDX #aa )
  REG-PC @ >ROM C@ DUP DUP REG-X ! FLAG-Z ! 80 AND FLAG-N !
  1 REG-PC+ 2 CYCLE+ ;
: DOBNE ( BNE <aa )
  FLAG-Z @ IF REG-PC @ >ROM CS@ 1+ REG-PC+ ELSE 1 REG-PC+ THEN
  3 CYCLE+ ;
: 6502EMU ( cycles -- )
  BEGIN CYCLE @ OVER  < WHILE
    REG-PC @ >ROM C@ 1 REG-PC+
    DUP 4C = IF DOJMP THEN      DUP A5 = IF DOLDA THEN
    DUP 85 = IF DOSTA THEN      DUP F0 = IF DOBEQ THEN
    DUP D0 = IF DOBNE THEN      DUP A9 = IF DOLDAI THEN
    DUP CA = IF DODEX THEN      DUP 88 = IF DODEY THEN
    DUP E6 = IF DOINC THEN      DUP A0 = IF DOLDY THEN
        A2 = IF DOLDX THEN
  REPEAT DROP ;

CREATE TESTCODE
  A9 C, 00 C,  ( start: LDA #0                                )
  85 C, 08 C,  (        STA 08                                )
  A2 C, 0A C,  (        LDX #10                               )
  A0 C, 0A C,  ( loop1: LDY #10                               )
  E6 C, 08 C,  ( loop2: INC 08                                )
  88 C,        (        DEY                                   )
  D0 C, FB C,  (        BNE loop2                             )
  CA C,        (        DEX                                   )
  D0 C, F6 C,  (        BNE loop1                             )
  4C C, 00 C, 80 C, (   JMP start                             )

: INIT-VM 13 0 DO                 ( Initialize the ROM        )
    I TESTCODE + C@ I ROM + C!
  LOOP
  0 CYCLE ! 8000 REG-PC ! ;

: BENCH6502 100 0 [ DECIMAL ] DO
    INIT-VM 6502 6502EMU [CHAR] . EMIT
  LOOP SPACE ;

13 Forth 83 Benchmark Versions

13.1 Benchme Helper

: benchme ( xt n -- ) \ executes the word with the execution token "xt" n-times
  dup >r              \ save number of iterations
  0 do dup execute loop \ execute word. word must have a neutral stack effect
  cr r> . ." Iterations." cr \ emit message
;

13.2 DUP-DROP

DECIMAL

: DDBENCH 1 32767 0 DO DUP DROP LOOP DROP ;

' DDBENCH 100 BENCHME

13.3 Integer Calculations

32000 constant intMax

variable intResult

: DoInt
  1 dup intResult dup >r !
  begin
    dup intMax <
  while
    dup negate r@ +! 1+
    dup r@ +! 1+
    r@ @ over * r@ ! 1+
    r@ @ over / r@ ! 1+
  repeat
  r> drop drop
;

13.4 Fibonacci Numbers

https://en.wikipedia.org/wiki/Fibonacci_number

Note: On an 8 or 16 bit machine, the Fibonacci numbers will roll over quickly and the programs will not produce a valid Fibonacci sequence anymore. But still the machines will do some number crunching work that will eat CPU time. We measure the time. The numbers are thrown away anyway.

13.5 Fibonacci 1

This version uses a recursive call. Recursive calls are not standardized in early Forth systems. The word to call the current definition can have different names in your forth (recurse, self, …). Please check you system documentation (if available) or the wordlist (using WORDS or VLIST).

: fib1 ( n1 -- n2 )
    dup 2 < if drop 1 exit then
    dup  1- recursive 
    swap 2- recursive  + ;
    
: fib1-bench 1000 0 do 
    20 0 do i fib1 drop loop
  loop ;

' fib1-bench 10 benchme

13.6 Fibonacci 2

: fib2 ( n1 -- n2 )                                                                
   0 1 rot 0 do 
      over + swap loop 
   drop ;
 
: fib2-bench 1000 0 do
    20 0 do i fib2 drop loop
  loop ;

' fib2-bench 10 benchme

13.7 Forth Nesting Benchmark

\ Forth nesting (NEXT) Benchmark                     cas20101204                   
: bottom ;                                                                         
: 1st bottom bottom ;  : 2nd 1st 1st ;      : 3rd 2nd 2nd ;                        
: 4th 3rd 3rd ;        : 5th 4th 4th ;      : 6th 5th 5th ;                        
: 7th 6th 6th ;        : 8th 7th 7th ;      : 9th 8th 8th ;                        
: 10th 9th 9th ;       : 11th 10th 10th ;   : 12th 11th 11th ;                     
: 13th 12th 12th ;     : 14th 13th 13th ;   : 15th 14th 14th ;                     
: 16th 15th 15th ;     : 17th 16th 16th ;   : 18th 17th 17th ;                     
: 19th 18th 18th ;     : 20th 19th 19th ;   : 21th 20th 20th ;                     
: 22th 21th 21th ;     : 23th 22th 22th ;   : 24th 23th 23th ;                     
: 25th 24th 24th ;                                                                 

: 32million   CR ." 32 million nest/unnest operations" 25th ;                      
:  1million   CR ."  1 million nest/unnest operations" 20th ;                      

CR .( enter 1million or 32million )

13.8 Forth Memory Move Benchmark

Note: The Forth Word MOVE always moves a cell. On Forth 79, Fig-Forth and Forth 83 Systems this is always 16 bit, not matter the CPU architecture. On more modern Forth, the call size is usually the CPU architecture bit size (32bit, 64bit or even 128bit). These machines need to move more data in this test. If you want, you can take this into account by dividing the count loop for the later two tests that use MOVE by the multiples of your cell size (2 for 32bit machines, 4 for 64bit etc).

\ Forth Memory Move Benchmark                       cas 20101204                   
 8192 CONSTANT bufsize                                                             
 VARIABLE buf1 HERE bufsize 1+ allot BUF1 !                                         
 VARIABLE buf2 HERE bufsize 1+ allot BUF2 !                                         
                                                                                    
 : test-CMOVE 49 0 DO BUF1 @ BUF2 @ bufsize CMOVE LOOP ;                            
                                                                                    
 : test-CMOVE> 49 0 DO BUF2 @ BUF1 @ bufsize CMOVE> LOOP ;                          
                                                                                    
 : test-MOVE> 49 0 DO BUF1 @ BUF2 @ bufsize MOVE LOOP ;                             
                                                                                    
 : test-<MOVE 49 0 DO BUF2 @ BUF1 @ bufsize MOVE LOOP ;     
 
 : move-bench test-CMOVE test-CMOVE> test-MOVE> test-<MOVE ;

13.9 Count bits in byte

\ Forth Benchmark - count bits in byte              cas 20101204

VARIABLE cnt

HEX 
: countbits ( uu -- #bits )
  cnt off
  8 0 DO dup 01010101  and cnt +!
         2/
  LOOP drop
  0 cnt 4 bounds DO i C@ + LOOP ;

DECIMAL

: bench5
  8192 0 DO I countbits drop LOOP ;

"BOUNDS" can be defined with:

( Convert str len to range for DO-loop )
: bounds ( str len -- str+len str )
  over + swap ;

"OFF" can be defined with:

( stores zero into address )
: OFF ( addr -- )
  0 SWAP ! ;

13.10 Sieve Benchmark

FIG-Forth derived systems or Forth-79 Systems require the initial value of a variable on the stack.

So instead of "VARIABLE FLAGS 0 FLAGS !" use "0 VARIABLE FLAGS".

\ Sieve Benchmark -- the classic Forth benchmark    cas 20101204                   
                                                                                    
 8192 CONSTANT SIZE   
 VARIABLE FLAGS  
 0 FLAGS !  
 SIZE ALLOT                         
                                                                                    
 : DO-PRIME                                                                         
   FLAGS SIZE 1 FILL  ( set array )                                                 
   0 ( 0 COUNT ) SIZE 0                                                             
   DO FLAGS I + C@                                                                  
     IF I DUP + 3 + DUP I +                                                         
        BEGIN DUP SIZE <                                                            
        WHILE 0   OVER FLAGS +  C!  OVER +  REPEAT                                  
        DROP DROP 1+                                                                
     THEN                                                                           
 LOOP                                                                               
 . ." Primes" CR ;

13.11 Greatest Common Divisor

13.12 GCD 1

\ gcd - greatest common divisor                     cas 20101204                   
                                                                                    
 : gcd ( a b -- gcd )                                                               
   OVER IF                                                                          
     BEGIN                                                                          
       DUP WHILE                                                                    
          2DUP U> IF SWAP THEN OVER -                                               
     REPEAT DROP ELSE                                                               
     DUP IF NIP ELSE 2DROP 1 THEN                                                   
   THEN ;  
   
: gcd1-bench 100 0 DO 
      100 0 DO j i gcd drop loop
      loop ;

13.13 GCD 2

another gcd with O(2) runtime speed

 : gcd2 ( a b -- gcd )                                                              
   2DUP        D0= IF  2DROP 1 EXIT   THEN                                          
   DUP          0= IF   DROP   EXIT   THEN                                          
   SWAP DUP     0= IF   DROP   EXIT   THEN                                          
   BEGIN  2DUP -                                                                    
   WHILE  2DUP < IF OVER -                                                          
                 ELSE SWAP OVER - SWAP                                              
                 THEN                                                               
   REPEAT NIP ;          

: gcd2-bench 100 0 DO 
      100 0 DO j i gcd2 drop loop
      loop ;

"D0=" compares a double integer against zero. It can be defined as:

: D0= ( d d -- f )
  + 0= ;

13.14 Takeuchi

( takeuchi benchmark in volksForth Forth-83 ) ( see http://en.wikipedia.org/wiki/Tak_(function) )

DECIMAL

 : 3dup 2 pick 2 pick 2 pick ;                                                        

 : tak ( x y z -- t )                                                                 
   over 3 pick < NEGATE IF nip nip exit then                                          
   3dup rot 1- -rot recursive >r                                                      
   3dup swap 1- -rot swap recursive >r                                                
             1- -rot recursive                                                        
   r> swap r> -rot recursive ;                                                        
                                                                                      
 : takbench ( -- )                                                                    
   0 1000 0 DO DROP 18 12 6 tak LOOP ;

13.15 Simple 6502 emulator

\ A simple 6502 emulattion benchmark                         cas                     
\ only 11 opcodes are implemented. The memory layout is:                             
\  2kB RAM at 0000-07FF, mirrored throughout 0800-7FFF                               
\ 16kB ROM at 8000-BFFF, mirrored at C000                                            
decimal                                                                              
create ram 2048 allot   : >ram $7FF  and ram + ;                                     
create rom 16384 allot  : >rom $3FFF and rom + ;                                     
\ 6502 registers                                                                     
variable reg-a   variable reg-x  variable reg-y                                      
variable reg-s   variable reg-pc  : reg-pc+ reg-pc +! ;                              
\ 6502 flags                                                                         
variable flag-c  variable flag-n   variable cycle                                    
variable flag-z  variable flag-v  : cycle+ cycle +! ;                                
hex                                                                                  
: w@ dup c@ swap 1+ c@ 100 * or ;                                                    
: cs@ c@ dup 80 and if 100 - then ;        

: read-byte ( address -- )                                                           
  dup 8000 < if >ram c@ else >rom c@ then ;                                          
: read-word ( address -- )                                                           
  dup 8000 < if >ram w@ else >rom w@ then ;                                          
: dojmp ( JMP aaaa )                                                                 
  reg-pc @ >rom w@ reg-pc ! 3 cycle+ ;                                               
: dolda ( LDA aa )                                                                   
  reg-pc @ >rom c@ ram + c@ dup dup reg-a !                                          
  flag-z ! 80 and flag-n ! 1 reg-pc+ 3 cycle+ ;                                      
: dosta ( STA aa )                                                                   
  reg-a @ reg-pc @ >rom c@ ram + c! 1 reg-pc+ 3 cycle+ ;                             
: dobeq ( BEQ <aa )                                                                  
  flag-z @ 0= if reg-pc @ >rom cs@ 1+ reg-pc+ else 1 reg-pc+ then 3 cycle+ ;   
: doldai ( LDA #aa )                                                                 
  reg-pc @ >rom c@ dup dup reg-a ! flag-z ! 80 and flag-n !                          
  1 reg-pc+ 2 cycle+ ;                                                               
: dodex ( DEX )                                                                      
  reg-x @ 1- FF and dup dup reg-x ! flag-z ! 80 and flag-n !                         
  2 cycle+ ;                                                                         
: dodey ( DEY )                                                                      
  reg-y @ 1- ff and dup dup reg-y ! flag-z ! 80 and flag-n !                         
  2 cycle+ ;                                                                         
: doinc ( INC aa )                                                                   
  reg-pc @ >rom c@ ram + dup c@ 1+ FF and dup -rot swap c! dup                       
  flag-z ! 80 and flag-n !  1 reg-pc+ 3 cycle+ ;                                     
: doldy ( LDY aa )                                                                   
  reg-pc @ >rom c@ dup dup reg-y ! flag-z ! 80 and flag-n !                          
  1 reg-pc+ 2 cycle+ ; 
: doldx ( LDX #aa )                                                                  
  reg-pc @ >rom c@ dup dup reg-x ! flag-z ! 80 and flag-n !                          
  1 reg-pc+ 2 cycle+ ;                                                               
: dobne ( BNE <aa )                                                                  
  flag-z @ if reg-pc @ >rom cs@ 1+ reg-pc+ else 1 reg-pc+ then                       
  3 cycle+ ;                                                                         
: 6502emu ( cycles -- )                                                              
  begin cycle @ over  < while                                                        
    reg-pc @ >rom c@ 1 reg-pc+                                                       
    dup 4C = if dojmp then      dup A5 = if dolda then                               
    dup 85 = if dosta then      dup F0 = if dobeq then                               
    dup D0 = if dobne then      dup A9 = if doldai then                              
    dup CA = if dodex then      dup 88 = if dodey then                               
    dup E6 = if doinc then      dup A0 = if doldy then                               
        A2 = if doldx then      repeat drop ; 

create testcode                                                                      
  A9 c, 00 c,  \ start: LDA #0                                                       
  85 c, 08 c,  \        STA 08                                                       
  A2 c, 0A c,  \        LDX #10                                                      
  A0 c, 0A c,  \ loop1: LDY #10                                                      
  E6 c, 08 c,  \ loop2: INC 08                                                       
  88 c,        \        DEY                                                          
  D0 c, FB c,  \        BNE loop2                                                    
  CA c,        \        DEX                                                          
  D0 c, F6 c,  \        BNE loop1                                                    
  4C c, 00 c, 80 C, \   JMP start 
                                                     
: init-vm 13 0 do i testcode + c@ i rom + c! loop                                    
          0 cycle ! 8000 reg-pc ! ;                                                  

: bench6502 100 0 do init-vm &6502 6502emu loop ;

13.16 Collatz

Rainer Glaschick hat einen Benchmark für das Collatz-Problem erstellt. Die Wikipedia über das Collatz-Problem: https://de.wikipedia.org/wiki/Collatz-Problem

Dieser Benchmark bricht ab, wenn die Zahlen fuer ein 16bit Forth zu gross werden.

( Benchmark mit der Collatz-Funktion  V1.1 RG 2017-10-05   )
(   c[n+1] = if even(c[n]) then c[n]/2 else 3*c[n]+1 fi    )
( Da der zweite Term immer gerade ist, wird                )
(   c[n+1] = if odd(c[n]) then c[n]/2 else (3*c[n]+1)/2 fi )
( Seien r[n] der Rest und q[n] der Quotient von c[n]/2,    )
( also c[n] = 2*q[n] + r[n], somit bei r[n] = 1:           )
( (3*c[n]+1)/2 = 3*q[n] + 2                                )
( Diese Version fuer 16-bit Rechner prueft vor einem       )
( Ueberlauf und bricht die Folge ab:                       )
( Damit 3*q+2<32767 ist, muss q<10922 sein.                )

( Collatz-Schritt. Null wenn Ueberlauf )
: cn+1 		( cn -- cm )
  2 /mod swap			
  if dup 10922 < 	( kein ueberlauf ? )
    if 3 * 2 + 
    else drop 0 then
  then
;
 
( Collatz-Folge drucken                         )
( dieses Wort wird im Benchmark nicht benoetigt )
( es druckt die Collatz-Folge aus               )

: coll. 	( cn -- )
  begin dup 1 > while
    cn+1 dup .
  repeat
  drop		( always 1 )
;
 
( Collatz-Folge zaehlen. Null wenn Ueberlauf )
: ccnt 		( cn -- cnt)
  0 swap 	( cnt cn )
  begin dup 1 > while
  cn+1 dup 
	if swap 1 + swap ( zaehlen )
	else drop 0
	then
  repeat
  drop
;
 
\ Maximum fuer alle Folgen bis k bestimmen
: cmax 		( k -- max )
  0 swap	( max k )
  begin dup 0 > while
    dup ccnt 	( max k cnt )
    rot  	( k cnt max )
    max		( k max )
    swap	( max k )
    1 -		( max k-1 )
  repeat
  drop
;

( Funktionstest, Ergebniss muss die Zahl "126" sein )
32101 cmax .
." = 126 ! "
 
( Benchmark-Schleife fuer schnelle Rechner > ~200Mhz )
: bench
  99 0 do 32101 cmax drop loop
;

13.17 Deliano

Ein Benchmark für 8bit Mikrocontroller, angeregt in Vierte Dimension 03/93 von Rafael Deliano

HEX 
5 CONSTANT FIVE 
VARIABLE BVAR 

: BENCH 
  100 0 DO 
    1 BEGIN 
        DUP SWAP 
        DUP ROT DROP 
        1 AND IF 
          FIVE + 
        ELSE 
          1- 
        THEN 
        BVAR ! BVAR @ 
        DUP 0100 AND 
     UNTIL DROP 
   LOOP ;

13.18 Palindrome numbers filtering

A Palindrome numbers filtering prepared by Francois Laagel

Tested with GNU/Forth and Z79Forth.

\ Palindrome numbers filtering [10..50000]. FLA Dec 10, 2020

: num>str ( n -- addr bytecount ) 0 <# #S #> ;

: lasteqfirst? ( addr offsetlast -- flag )
  OVER + C@ SWAP C@ = ;

: ispalindrome? ( addr offsetlast -- flag )
  DUP 1 <              IF 2DROP 1 EXIT THEN
  2DUP lasteqfirst? 0= IF 2DROP 0 EXIT THEN
  2 - SWAP 1+ SWAP RECURSE ;

: pal ( -- ) CR 10 BEGIN
    DUP   num>str  \ n\addr\bcount
    2DUP 1-        \ n\addr\bcount\addr\bcount-1
    ispalindrome?  \ n\addr\bcount\flag
    IF TYPE SPACE
    ELSE 2DROP THEN
    1+ DUP 50000 =
  UNTIL DROP ;

14 TODO ANS-Forth (94) Benchmark Versions