Basicprogramming(.org) > General questions and discussions

Integer/looping benchmark

(1/2) > >>

Ed Davis:
Here is the latest update of the integer intensive interpreter benchmark. Interestingly, the fastest interpreter I tested is over 7 times slower than optimized C.

What is the purpose of this?

I enjoy fiddling with compilers/interpreters, especially those that are simple enough that I can understand. I also enjoy writing my own.  I wanted to find out what makes some interpreters so much faster than others, and why are others so slow. Examining the source to some of these interpreters has helped me learn some of the reasons, and has helped to improve the speed of those I'm working on.

Here is the test code in fairly standard Basic:


--- Code: ---accum = 0
count = 0
while count < 1545
    leftedge   = -420
    rightedge  =  300
    topedge    =  300
    bottomedge = -300
    xstep      =  7
    ystep      =  15

    maxiter    =  200

    y0 = topedge
    while y0 > bottomedge
        x0 = leftedge
        while x0 < rightedge
            y = 0
            x = 0
            thechar = 32
            xx = 0
            yy = 0
            i = 0
            while i < maxiter and xx + yy <= 800
                xx = int((x * x) / 200)
                yy = int((y * y) / 200)
                if xx + yy > 800 then
                    thechar = 48 + i
                    if i > 9 then
                        thechar = 64
                    end if
                else
                    temp = xx - yy + x0
                    if (x < 0 and y > 0) or (x > 0 and y < 0) then
                        y = int(-1 * (-1 * x * y) / 100) + y0
                    else
                        y = int(x * y / 100) + y0
                    end if
                    x = temp
                end if

                i = i + 1
            wend
            x0 = x0 + xstep
            accum = accum + thechar
        wend
        y0 = y0 - ystep
    wend

    if count mod 300 = 0 then
        print accum,
    end if
    count = count + 1
wend

print accum

--- End code ---

This is the output:


200574 60372774 120544974 180717174 240889374 301061574 309886830


This is a pretty intense integer benchmark!

Note this funky code:

--- Code: ---    if (x < 0 and y > 0) or (x > 0 and y < 0) then
        y = int(-1 * (-1 * x * y) / 100) + y0
    else
        y = int(x * y / 100) + y0
    end if

--- End code ---

It turns out that there is no consensus as to whether integer division, when one of the operands is negative, should round towards zero, negative infinity, or positive infinity.

Python and Ruby both round towards negative infinity.  C rounds towards zero.

In order to get the same output from each language (to verify that each language was essentially computing the same thing and doing similar work), I had to figure out how to preclude one of the operands from being negative.

The code checks, and if either x or y is < 0 (but not both), then it multiplies by minus one to force positive division, and then by minus one again at the end to restore the sign.

Below are the tests that I have run.  I would welcome your additions and/or suggestions.

Test machine:
Windows 7, Service Pack 1, 64-bit
Intel Core i7-3720QM CPU @2.60GHz
16.0 GB (15.9 usable)

In the tables below

* Native means that the code is compiled to machine code, one way or another, and an .exe is created.
* JIT means that the code is only compiled to machine code on a Just In Time basis.
* VM means that the code is compiled into virtual machine code, and that VM code is executed by a VM interpreter.
* Interp means that the code is not compiled but interpreted - it may be tokenized though.
* ? means I don't know how this processor works.  Updates are appreciated!Basic compiler/interpreters:

FreeBasic                  1.09 seconds NativeBasic Compiler                                BCX                        1.12 seconds NativeBasic to C translator                         VisualBasic.Net            1.52 seconds JIT                                                 Oxygen Basic               3.77 seconds Native                                              PowerBasic                 4.03 seconds Native                                              QB64                      32.43 seconds NativeBasic to C++ translator                       JWillia basic            109    seconds VM    Basic interpreter                             ChipMunkBasic            216    seconds Interp                                              Yabasic                  278    seconds VM                                                  SdlBasic                 310    seconds ?                                                   SmallBASIC               354    seconds ?                                                   SpecBAS                  358    seconds VM    Basic interpreter                             BBCBasic                 531    seconds ?                                                   ThinBasic                543    seconds ?                                                   FBSL                     551    seconds ?     Basic interpreter                             Scriba                   618    seconds ?     Basic interpreter                             RCBasic                  778    seconds ?                                                   LBB                     1502    seconds ?     Liberty Basic Booster                         DDS5                    3033    seconds InterpExtended Tiny Basic                           my-basic                3302    seconds ?                                                   MiniBASIC               5471    seconds Interp                                              nuBASIC                 8132    seconds ?                                                   Basic256              18852    seconds ?                                                   bscript                21558    seconds ?     Basic interpreter                             
Various Toy implementations - mainly to experiment with speeds of various implementations:

Toy7.c                     7.80 seconds VM    gcc goto's, TOS, superinstructions            Toy6.c                    19.76 seconds VM    gcc goto's                                    Toy.bas                   33.35 seconds VM    compiled with FreeBASIC -lang qb -O 3         Toy5.c                    53.48 seconds VM    Simple stack-based VM, standard C switch      Toy.bas Oxygen ver.       82.34 seconds VM    console integer version - float version fails Toy - tokenized, no VM   137    seconds InterpTokenizing interpreter - no VM                Toy - pure interpreter  1154    seconds Interppure-interpreter - re-lexes each token - no VM
All the rest:

gcc C -O3 or -O2           1.00 seconds Native                                              FreeBasic                  1.09 seconds NativeBasic Compiler                                BCX                        1.12 seconds NativeBasic to C translator                         Nim                        1.12 seconds Native                                              gcc C -O  or -O1           1.13 seconds Native                                              Java                       1.23 seconds JIT                                                 C#                         1.34 seconds JIT                                                 VisualBasic.Net            1.52 seconds JIT                                                 FreePascal                 1.92 seconds Native                                              C, no options              1.96 seconds Native                                              C -Os                      2.38 seconds Native                                              Borland C                  2.80 seconds Native                                              TinyC                      3.23 seconds Native                                              euc -gcc -con              3.58 seconds NativeEuphoria to C translator                      Oxygen Basic               3.77 seconds Native                                              PowerBasic                 4.03 seconds Native                                              Fast Toy.c                 7.80 seconds VM    gcc goto's, TOS, superinstructions            Javascript via node.js    10.23 seconds JIT                                                 pe 64-bit                 14.26 seconds VM                                                  pe 32-bit                 17.96 seconds VM                                                  Toy6.c                    19.76 seconds VM    gcc goto's                                    Java -Xint                21.24 seconds VM    Java without JIT                              QB64                      32.43 seconds NativeBasic to C++ translator                       Toy.bas                   33.35 seconds VM    compiled with FreeBASIC -lang qb -O 3         Euphoria v4.1 beta 2      35.66 seconds VM                                                  Pike                      44.39 seconds VM    C like interpreter                            Toy5.c                    53.48 seconds VM                                                  TinyPas.c                 58.97 seconds VM    Pascal-S converted to C.                      Ruby                      60.25 seconds VM                                                  SAL                       67.22 seconds VM                                                  vspl                      68.76 seconds VM                                                  Lua                       80.14 seconds VM                                                  php                       81.23 seconds VM                                                  Toy.bas Oxygen ver.       82.34 seconds VM    console integer version - float version fails Wren                      84.57 seconds VM                                                  PL0.c                     97.33 seconds VM    Wirth's 1976 Tiny Pascal converted to C       C4                        97.80 seconds VM    C subset interpreter                          UnderC                   103    seconds VM    C++ interpreter                               JWillia basic            109    seconds VM    Basic interpreter                             Toy - tokenized, no VM   137    seconds InterpTokenizing interpreter - no VM                hoc                      140    seconds VM    Higher Order Calculator                       Lily                     162    seconds VM                                                  NaaLaa                   168    seconds VM                                                  CInt                     201    seconds VM    C++ interpreter                               ChipMunkBasic            216    seconds Interp                                              Python                   274    seconds VM                                                  Yabasic                  278    seconds VM                                                  SdlBasic                 310    seconds ?                                                   Hanson-calc              321    seconds VM    Hanson's version of hoc                       SmallBASIC               354    seconds ?                                                   SpecBAS                  358    seconds VM    Basic interpreter                             BBCBasic                 531    seconds ?                                                   ThinBasic                543    seconds ?                                                   FBSL                     551    seconds ?     Basic interpreter                             Ch                       582    seconds ?     C interpreter                                 Scriba                   618    seconds ?     Basic interpreter                             RCBasic                  778    seconds ?                                                   SI                      1020    seconds InterpC subset interpreter                          Toy - pure interpreter  1154    seconds Interppure-interpreter - re-lexes each token - no VMLBB                     1502    seconds ?     Liberty Basic Booster                         LittleC                 2160    seconds InterpC subset interpreter                          PicoC                   2352    seconds ?     C interpreter                                 DDS5                    3033    seconds InterpExtended Tiny Basic                           my-basic                3302    seconds ?                                                   MiniBASIC               5471    seconds Interp                                              nuBASIC                 8132    seconds ?                                                   Basic256              18852    seconds ?                                                   bscript                21558    seconds ?     Basic interpreter                             

jcfuller:
Ed,
  Nice work!!
Are  the BCX numbers relative to the c/c++ compiler used.
If so please list the compiler for the BCX test.
James


Ed Davis:

--- Quote from: jcfuller on April 20, 2016, 09:53:49 AM ---Are  the BCX numbers relative to the c/c++ compiler used.

--- End quote ---

Most assuredly.


--- Quote ---If so please list the compiler for the BCX test.

--- End quote ---

3 tries for each one, taking the lowest number.

gcc (tdm64-1) 5.1.0

    -s -Ofast -m64  1.17
    -s -Ofast -m32  1.43


gcc (tdm64-2) 4.8.1

    -s -Ofast -m64  1.12
    -s -Ofast -m32  1.43


I've noticed that 5.1 is slightly slower that 4.81 in some things, however 5.1 beats 4.81 in a few of my tests too.

wang renxin:
Great job Ed. FYI. MY-BASIC works as an interpreter.

ZXDunny:
FWIW, I've made quite a lot of changes to code flow in specbas just recently - cached GOTO/GOSUB and incomplete boolean evaluation so will likely shave a few seconds off that time. I'll release it soon.

D.

Navigation

[0] Message Index

[#] Next page

Go to full version