Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to make your code faster
#1
One of the reasons you are probably looking at this is that you have some idea how to program in Sinclair Basic, and no idea how to code in machine code (or z80 assembler as it's sometimes called). You want to go play with the old spectrum stuff, and want faster programs - and it must be easier these days, right?

Well, with Boriel's compiler, it is. Most programs can be put into the compiler in a form almost identical to an original sinclair basic program, and it will work. It will be faster. But you want to make it as fast as you can, right?

First thing then: variable types. (see http://www.boriel.com/wiki/en/index.php/ZX_BASIC:Types for details on what variable types the compiler supports.)

Nothing you can do to your program will make as big a speed increase as making sure you use the smallest variable type possible in every case. A byte is better than an integer is better than a long and all those are better than using floating point numbers if you can avoid them.

Have a look at this program:

Code:
FUNCTION t AS ULONG
    RETURN INT((65536 * PEEK (23674) + 256 * PEEK(23673) + PEEK (23672)))
END FUNCTION

DIM i,j,k,fake as <insert type here>
DIM time as uLong
let fake=0

CLS

PRINT "Loop Start"
LET TIME=t()
for k=1 to 20    
    for j=1 to 125
        for i = 1 to 125
        LET fake=fake+1-(fake/2)
        next i
    next j
next k

PRINT "loop End"

print t()-TIME

If we set the type of variable for i,j,k,fake as FLOAT up there at the top, this program will disappear for ages before it reports that it took 119,551 frames to come back. That's almost 40 minutes! If you change the type of variable there to UBYTE it comes back in 839 frames. That's under 17 seconds. To put it another way, the code runs over 142 times faster. Variable types make a BIG difference!

NOTE: The nearest Sinclair BASIC equivalent of this program runs in 235,726 frames, or just over 78 minutes to do the same thing. Even using the same variable types as Sinclair BASIC (Which always uses five byte FLOAT types), a compiled program is quite a lot faster!

For the above program, here are the times, in frames (a frame is 1/50th of a second. Divide by 50 to get a time in seconds if you want - I left it this way to make a speed comparison)

Code:
uByte =     839
Byte  =     861
uinteger=  1126
integer =  1178
uLong =   31792
Long  =   32895
Fixed =   36711
Float =  119551

The rule is use the smaller one every time you can, especially in loops! If you're only going round a for/next loop about 10 times, use uByte.

If you can get away with positive numbers, unsigned types (uByte, uIntger and uLong) are a little bit faster than signed ones.

You may also be able to eliminate floating point numbers by multiplying up - for example store $3.02 as 302 pennies.

[Note: In computing terms generally (not just on the spectrum) there are good reasons not to store money in floating point numbers anyway - floating point numbers are NOT perfectly accurate and you may get rounding errors that could cause problems later on. Just as in decimal you can't write 1/3 without an infinitely long 0.33333333->forever happening, you can't store something like 0.1 in binary without an infinitely long binary number. So, far better to store currency as the smaller unit in an integer or long type. A long would allow you to keep track of up to +/- 2,147,483,647 pennies - or about 21 million currency units. If you want to track more than that you can definitely afford a more powerful computer than a Spectrum!]
Reply


Messages In This Thread

Forum Jump:


Users browsing this thread: 1 Guest(s)