Cost of BASIC operations

The place for codemasters or beginners to talk about programming any language for the Spectrum.
Post Reply
User avatar
Hedge1970
Manic Miner
Posts: 388
Joined: Mon Feb 18, 2019 2:41 pm

Re: Cost of BASIC operations

Post by Hedge1970 »

Well I just bit the bullet and moved, renumbered, deleted and then edited Gosubs and Goto in 150 odd lines of code to get the game loop at the top of the page (along with the gosubs)... but its made a big difference :)

Still working on the game but this is a really good change so thank you for the push :D .
User avatar
djnzx48
Manic Miner
Posts: 730
Joined: Wed Dec 06, 2017 2:13 am
Location: New Zealand

Re: Cost of BASIC operations

Post by djnzx48 »

I wonder if program speed could be improved by doing something like DIM a(100) at the start of a program to create a large array, and storing all of your numeric variables somewhere within that array. Essentially putting your own code in charge of memory management. Then the time spent looking up the variable name would be minimised, and the interpreter could just jump straight to where each variable is within the array from the subscript.
User avatar
Joefish
Rick Dangerous
Posts: 2058
Joined: Tue Nov 14, 2017 10:26 am

Re: Cost of BASIC operations

Post by Joefish »

Don't put your startup code at the top. Just one GOSUB or GOTO to your title screen. The title screen code should then flow into code to initialise the game before it returns, so your game loop starts at the second line of code in the listing.

Also use multi-statement lines (use ':') as much as you can to reduce your use of line numbers, which makes them easier for the interpreter to skip over. (But note that whether your line numbers go up in 1s or 10s, that makes no difference).

If a routine is called EVERY cycle of the game, then just write it into the main loop. Sub-routines that are called periodically should be placed just after the main game loop as they're not quite so important.

If you've got one major sub-routine that is sometimes needed and sometimes not, you can place it directly after your main program loop, and sometimes just let your program loop run on into it (by conditionally skipping the last GOTO). Then at the end of this 'sub-routine' is the same GOTO to go back to the start of your program loop.
User avatar
Hedge1970
Manic Miner
Posts: 388
Joined: Mon Feb 18, 2019 2:41 pm

Re: Cost of BASIC operations

Post by Hedge1970 »

Joefish wrote: Thu Mar 14, 2019 11:57 am Don't put your startup code at the top. Just one GOSUB or GOTO to your title screen. The title screen code should then flow into code to initialise the game before it returns, so your game loop starts at the second line of code in the listing.
Thanks for the clarification this is what i've implemented. Ive left a number of lines should I need them but as its stands its 10 - screen and set up 50 Main loop.
Joefish wrote: Thu Mar 14, 2019 11:57 am Also use multi-statement lines (use ':') as much as you can to reduce your use of line numbers, which makes them easier for the interpreter to skip over. (But note that whether your line numbers go up in 1s or 10s, that makes no difference).
This is absolute Gold dust! My main loop is approx. 85 lines but I believe I have the scope for removing around 20 lines - many or which are REMs but also some further optimisation based on your recommendation here and your previous recommendation to keep the loop as small/tight as possible.

Joefish wrote: Thu Mar 14, 2019 11:57 am If a routine is called EVERY cycle of the game, then just write it into the main loop. Sub-routines that are called periodically should be placed just after the main game loop as they're not quite so important.

If you've got one major sub-routine that is sometimes needed and sometimes not, you can place it directly after your main program loop, and sometimes just let your program loop run on into it (by conditionally skipping the last GOTO). Then at the end of this 'sub-routine' is the same GOTO to go back to the start of your program loop.
I have accidentally managed to avoid this in my design so all good.

Thanks again
User avatar
Joefish
Rick Dangerous
Posts: 2058
Joined: Tue Nov 14, 2017 10:26 am

Re: Cost of BASIC operations

Post by Joefish »

Yeah, REMs might help to make things more readable, but really they just slow things down.
spectron
Drutt
Posts: 25
Joined: Thu Mar 29, 2018 3:27 pm

Re: Cost of BASIC operations

Post by spectron »

Ralf wrote: Wed Mar 13, 2019 6:33 pm and it's big performance boost, 300%, 500% or so.
Way more than that for most compilers, especially those that only allow for Integer values (which is all you really need if you're doing a game)
User avatar
djnzx48
Manic Miner
Posts: 730
Joined: Wed Dec 06, 2017 2:13 am
Location: New Zealand

Re: Cost of BASIC operations

Post by djnzx48 »

YS did some nice benchmarks here. If these results are representative of real-world programs then that does seem pretty speedy!
IgnaCoBo
Drutt
Posts: 18
Joined: Tue Nov 16, 2021 9:11 am

Re: Cost of BASIC operations

Post by IgnaCoBo »

Hi,
I might be 2 years late, but, check these tips I use to improve speed in my Basic programs:
viewtopic.php?f=3&t=5535&p=78880&hilit= ... ack#p78880
megaribi
Drutt
Posts: 15
Joined: Thu Nov 25, 2021 4:31 pm

Re: Cost of BASIC operations

Post by megaribi »

Ralf wrote: Wed Mar 13, 2019 6:33 pm There are compilers for Spectrum Basic available and although I have very little personal experience with it, I remember seeing them in action and it's big performance boost, 300%, 500% or so. I believe you'll never achieve similar improvement with optimisation tricks, maybe unless you change your algorythm.
I have checked many Spectrum BASIC compilers, and the best is Hisoft BASIC. At first, it seems a bit harder to use than MCoder 2, because you need to add REM : OPEN # command at the program beginning, and declare as much variables to be integer as possible adding command REM : INT I,J,K,SUM but, you will get very fast standalone machine code program (not dependant on compiler in memory).

If you wish to stick with interpreted BASIC I have some more hints to speed it up.
  • Do not define UDG using READ ... DATA. Better, define them separately, and just load them using LOAD "" CODE USR "A" .
  • Define strings at the program initialization to maximal length using DIM A$(256) to avoid insertion
  • Do not try to reduce memory usage by LET A=VAL "30". Stick with plain LET A=30
  • Instead IF A=5 AND B=5 THEN ... better do IF A=5 THEN IF B=5 THEN ....
  • Try to prepare program/game background in one long string like

Image
Then one PRINT A$ will display your background in a blink of eye.
  • Put the most time critical code at the start of the program
  • First assign values to the most commonly used variables
  • Use single letter variable names where possible
  • ATTR is faster than SCREEN$
  • Do not repeat IF INKEY$="..." for every key. Better do LET V=CODE INKEY$ and compare v variabble with ASCII codes
  • BEEP stops program completely. To avoid mute game, use some OUT 254,n commands
  • When possible, use multiplication instead division. LET A=.5*B is 10% faster than LET A=B/2
  • Pre-calculate constants. Better write 1.5*A instead 3/*A/2
  • Avoid transcendent functions. Steven Vickers, although he had PhD in mathematics, generated Chebyshev polynomials for every calculations, although he had to do it only once statically. Table of possible values is better solution
Post Reply