Memory saving in BASIC - summary table

The place for codemasters or beginners to talk about programming any language for the Spectrum.
michellekg
Drutt
Posts: 35
Joined: Tue Nov 14, 2017 9:54 pm
Location: St. Petersburg
Contact:

Memory saving in BASIC - summary table

Post by michellekg »

Gentlemen, I've decided to summarize in one table all numbers' memory-saving tricks in BASIC. I took all of already known tricks and added a lot of my own, freshly discovered ones. Sometimes it can be very useful to save a few bytes.

If you find something that I missed - feel free to write here or leave comments in the table, everyone has access to it (like commentators, of course), I will then add everything that fits. There are two tabs in the table - with Russian and English versions (just for your convenience):

https://docs.google.com/spreadsheets/d/ ... d=16862986

michellekg
Drutt
Posts: 35
Joined: Tue Nov 14, 2017 9:54 pm
Location: St. Petersburg
Contact:

Re: Memory saving in BASIC - summary table

Post by michellekg »

Massive update - several hundreds new numbers added! Mostly fractional numbers between 0 and 2, and negative numbers, but there are also useful values between 1 and 255. Thanks to Ru Guevara!
equinox
Dynamite Dan
Posts: 1052
Joined: Mon Oct 08, 2018 1:57 am
Location: SE England

Re: Memory saving in BASIC - summary table

Post by equinox »

michellekg wrote: Thu Dec 14, 2023 4:56 am Gentlemen, I've decided to summarize in one table all numbers' memory-saving tricks in BASIC. I took all of already known tricks and added a lot of my own, freshly discovered ones. Sometimes it can be very useful to save a few bytes.
Hi. This is funny and I think you should put a warning or disclaimer on it: like "this can save you 2 or 3 bytes but it will make your code less maintainable AND less portable" (do you really think that PEEK PI is forward-compatible? Imagine the C++ committee screaming.) By the way some of these function calls are noticeably expensive too, and you will take a speed hit. You can smoke a cigar while waiting for SQR to return. Hahah... yes... you can make Speccy BASIC even slower, trust me.

Other than that: if you say "here is a way to save a few bytes on an original Spectrum ROM" I think it's ace, please CONTINUE.

Andrew Owen also wants you to know that if you put your most frequently called DEF FN and DATA statements in the first line of your program, you will save literal milliseconds.

Personally if I was at a sleeping-under-the-table demoparty and I saw someone type 2000 instead of 2e3, I would never respect them again, and certainly not invite them under the table.
equinox
Dynamite Dan
Posts: 1052
Joined: Mon Oct 08, 2018 1:57 am
Location: SE England

Re: Memory saving in BASIC - summary table

Post by equinox »

If you also really hate portability, and reality, I heard that PEEK VAL "23693" is a great way to encode the value 56.
Dunny is physically trying to restrain me as I type. Hahaha take that DUNnyfgddgf
AndyC
Dynamite Dan
Posts: 1408
Joined: Mon Nov 13, 2017 5:12 am

Re: Memory saving in BASIC - summary table

Post by AndyC »

Can you be less portable when using Sinclair BASIC? It's already weird enough as it is.

But yeah, this sort of thing will definitely make your code slower and Sinclair BASIC is already glacial.
equinox
Dynamite Dan
Posts: 1052
Joined: Mon Oct 08, 2018 1:57 am
Location: SE England

Re: Memory saving in BASIC - summary table

Post by equinox »

Further tips for memory saving in BASIC:

1. Compile it with HiSoft.
2. Use the HiSoft directives like REM:INT when it's a cheesy loop variable.
3. Get a C64 BBC Micro you clown.

Actually that would be a good related thread: we don't care about memory because it's a Spectrum and we already know we've got about 40K max. But what if we want to write really fast BASIC?

equinox's tips for writing really fast BASIC:

1. Put all DEF FNs and DATA statements at the top of program (line 0 or 1) because apparently we are too dumb even to write an index table of lines to addresses -- or maybe it's too expensive. Nine Tiles, what were you thinking? You were thinking "oh hell it has to be done by Thursday".
2. Reduce everything to single expressions, so instead of writing IF x THEN PRINT, IF y THEN PRINT, do awful stuff like PRINT (x AND "blah");(y AND "blah")
3. thinkey$
4. Get a C64 BBC Micro you clown.
User avatar
+3code
Manic Miner
Posts: 433
Joined: Sat Mar 19, 2022 7:40 am

Re: Memory saving in BASIC - summary table

Post by +3code »

equinox wrote: Tue Dec 19, 2023 6:18 pm ...apparently we are too dumb even to write an index table of lines to addresses -- or maybe it's too expensive. Nine Tiles, what were you thinking? You were thinking "oh hell it has to be done by Thursday".
https://spectrumcomputing.co.uk/entry/8 ... ster_BASIC

IIRC, is mostly the same, but with an index table to speed up gotos, gosubs and the others.
C.Born
Manic Miner
Posts: 229
Joined: Sat Dec 09, 2017 4:09 pm

Re: Memory saving in BASIC - summary table

Post by C.Born »

pitty for some off you you dont get the subject
this is about SMALL BASIC in zx
so
NO it AINT C !!
its all tokenised coding
i like it and can use some off them especialy if you only have 100 byte left for a decent LOADER
did you ever write a LOADER for your C ??
bet its in BASIC ??
equinox
Dynamite Dan
Posts: 1052
Joined: Mon Oct 08, 2018 1:57 am
Location: SE England

Re: Memory saving in BASIC - summary table

Post by equinox »

michellekg wrote: Thu Dec 14, 2023 4:56 am Gentlemen, I've decided to summarize in one table all numbers' memory-saving tricks in BASIC.
By the way, I don't think you are being consistent about INT. For example you give PI as the value 3 (which will work where there is implicit rounding, like INK PI), but in floating-point contexts of course that won't work. Then you define 15 as INT SQR PEEK PI (something only a fandom could love). If it's an integer context, we wouldn't need INT.
equinox
Dynamite Dan
Posts: 1052
Joined: Mon Oct 08, 2018 1:57 am
Location: SE England

Re: Memory saving in BASIC - summary table

Post by equinox »

Also, because some people will read this as "what is the smallest number of keywords that will generate a number": you should probably remark upon the strangeness of BIN. The value of BIN is zero (e.g, PRINT BIN) but it doesn't save space like the other keywords, because it generates the same "number noise" (is there an actual name for this?) as other numeric literals in ZX BASIC. It's worth stating this in your file because people may reasonably (wrongly) assume that BIN is only 1 byte.

(unrelated) I also really dislike BIN because it treats digits like a string, but doesn't actually require a string (no quotes). One of the various issues where Speccy BASIC fails... not the most important issue.
User avatar
1024MAK
Bugaboo
Posts: 3123
Joined: Wed Nov 15, 2017 2:52 pm
Location: Sunny Somerset in the U.K. in Europe

Re: Memory saving in BASIC - summary table

Post by 1024MAK »

@equinox if you really want to make a ZX Spectrum slower, I can do that for you.
Oh, and if you want a fast BASIC, use a Acorn BBC Master Turbo (with a 4MHz internal co-processor board), or better still, a Raspberry Pi co-processor...

Mark
:!: Standby alert :!:
“There are four lights!”
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb :dance
Looking forward to summer later in the year.
equinox
Dynamite Dan
Posts: 1052
Joined: Mon Oct 08, 2018 1:57 am
Location: SE England

Re: Memory saving in BASIC - summary table

Post by equinox »

1024MAK wrote: Tue Dec 19, 2023 7:44 pm Oh, and if you want a fast BASIC, use a Acorn BBC Master Turbo (with a 4MHz internal co-processor board), or better still, a Raspberry Pi co-processor...
Yeah yeah I'm drooling. I love BBCs (I think there's a case to say that they were designed in the good nerd way, like Unix etc.) but I don't usually talk about them, because here it's off-topic, and on the Beeb forum I am even more ignorant than here. I could also bxch about screen modes etc. But you are absolutely correct: BBC BASIC is much better than the Speccy one and may even take less space, I haven't checked. If I could add ONE thing to Speccy BASIC it would obviously be scoped local variables (cf. BBC's "DEFPROC", or various cool features on the Sam Coupé), I hope this isn't controversial. The irony is that if you write Z80 then you already have a bloody stack, it's there!
User avatar
WhatHoSnorkers
Manic Miner
Posts: 254
Joined: Tue Dec 10, 2019 3:22 pm

Re: Memory saving in BASIC - summary table

Post by WhatHoSnorkers »

+3code wrote: Tue Dec 19, 2023 6:53 pm https://spectrumcomputing.co.uk/entry/8 ... ster_BASIC

IIRC, is mostly the same, but with an index table to speed up gotos, gosubs and the others.
Now that's intriguing. Will have to have a look and compare with the Zip Compiler...
I have a little YouTube channel of nonsense
https://www.youtube.com/c/JamesOGradyWhatHoSnorkers
User avatar
+3code
Manic Miner
Posts: 433
Joined: Sat Mar 19, 2022 7:40 am

Re: Memory saving in BASIC - summary table

Post by +3code »

WhatHoSnorkers wrote: Tue Dec 19, 2023 8:27 pm Now that's intriguing. Will have to have a look and compare with the Zip Compiler...
Well, it's interpreted, so in any case should be the Zip Compiler faster, I assume. It's simply a 1300 bytes patch to the standard interpreter.
sn3j
Manic Miner
Posts: 500
Joined: Mon Oct 31, 2022 12:29 am
Location: Germany

Re: Memory saving in BASIC - summary table

Post by sn3j »

32..128 = CODE "?", where ? represents the appropriate character
POKE 23614,10: STOP      1..0 hold, SS/m/n colors, b/spc toggle
C.Born
Manic Miner
Posts: 229
Joined: Sat Dec 09, 2017 4:09 pm

Re: Memory saving in BASIC - summary table

Post by C.Born »

sn3j wrote: Tue Dec 19, 2023 9:56 pm 32..128 = CODE "?", where ? represents the appropriate character
Indeed ! its a '4'
michellekg
Drutt
Posts: 35
Joined: Tue Nov 14, 2017 9:54 pm
Location: St. Petersburg
Contact:

Re: Memory saving in BASIC - summary table

Post by michellekg »

C.Born wrote: Tue Dec 19, 2023 7:06 pm pitty for some off you you dont get the subject
this is about SMALL BASIC in zx
Thanks. You're absolutely right, it's for loaders, byte saving contests etc.

Well, at least 7 people got it, including you! Glad to help.
michellekg
Drutt
Posts: 35
Joined: Tue Nov 14, 2017 9:54 pm
Location: St. Petersburg
Contact:

Re: Memory saving in BASIC - summary table

Post by michellekg »

equinox wrote: Tue Dec 19, 2023 7:35 pm Also, because some people will read this as "what is the smallest number of keywords that will generate a number": you should probably remark upon the strangeness of BIN. The value of BIN is zero (e.g, PRINT BIN) but it doesn't save space like the other keywords, because it generates the same "number noise" (is there an actual name for this?) as other numeric literals in ZX BASIC. It's worth stating this in your file because people may reasonably (wrongly) assume that BIN is only 1 byte.
It literally says so in my spreadsheet:

BIN | 7 (bytes)

And remark: "Despite the absence of the parameter, the BASIC still writes a whole 6 bytes after BIN for it."
michellekg
Drutt
Posts: 35
Joined: Tue Nov 14, 2017 9:54 pm
Location: St. Petersburg
Contact:

Re: Memory saving in BASIC - summary table

Post by michellekg »

equinox wrote: Tue Dec 19, 2023 4:42 pm Hi. This is funny and I think you should put a warning or disclaimer on it: like "this can save you 2 or 3 bytes but it will make your code less maintainable AND less portable" (do you really think that PEEK PI is forward-compatible? Imagine the C++ committee screaming.
Well, I assumed that people who still use Sinclair BASIC know that these kinds of functions slow down execution, and would only use this table to save space. But perhaps you are right, and such a disclaimer is worth adding!
michellekg
Drutt
Posts: 35
Joined: Tue Nov 14, 2017 9:54 pm
Location: St. Petersburg
Contact:

Re: Memory saving in BASIC - summary table

Post by michellekg »

equinox wrote: Tue Dec 19, 2023 5:07 pm If you also really hate portability, and reality, I heard that PEEK VAL "23693" is a great way to encode the value 56.
Dunny is physically trying to restrain me as I type. Hahaha take that DUNnyfgddgf
Nah, not worth it. It's 9 bytes (new) vs 8 (old)!
michellekg
Drutt
Posts: 35
Joined: Tue Nov 14, 2017 9:54 pm
Location: St. Petersburg
Contact:

Re: Memory saving in BASIC - summary table

Post by michellekg »

equinox wrote: Tue Dec 19, 2023 7:32 pm By the way, I don't think you are being consistent about INT. For example you give PI as the value 3 (which will work where there is implicit rounding, like INK PI), but in floating-point contexts of course that won't work. Then you define 15 as INT SQR PEEK PI (something only a fandom could love). If it's an integer context, we wouldn't need INT.
Not really. The table notes that PI will produce a value with a fraction and even specifies the exact value (3.1415927). But it takes only one byte and is suitable for many cases. But next to it is the integer value INT PI, which takes 2 bytes.

The number 15 has an integer value and 4 bytes/tokens, but no fractional value of 3 bytes or less.

All numbers is color coded, please look at the explanations in the same table.
sn3j
Manic Miner
Posts: 500
Joined: Mon Oct 31, 2022 12:29 am
Location: Germany

Re: Memory saving in BASIC - summary table

Post by sn3j »

-5.3899113 = LN RND (after RANDOMIZE PI)

11 = LEN STR$ RND (after RANDOMIZE PI)

It's also possible to use RND multiple times once the sequence is fixed.
And some numbers below 32 might also be obtained with CODE "x" - depends if the program needs to list properly.
POKE 23614,10: STOP      1..0 hold, SS/m/n colors, b/spc toggle
C.Born
Manic Miner
Posts: 229
Joined: Sat Dec 09, 2017 4:09 pm

Re: Memory saving in BASIC - summary table

Post by C.Born »

there are some tricks that only work in the 48K editor like changing the Brackets of an calculation for aculades,
but MIND those do WORK in 128 but as soon as you edit the TOKENS WILL BE REVERTED TO CHR$ again
its an "edit vulnerable trick" ??

Code: Select all


INT     (RND*8+.5) = 9+6+6
INT VAL "RND*8+.5" = 10
User avatar
TMD2003
Rick Dangerous
Posts: 2043
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Re: Memory saving in BASIC - summary table

Post by TMD2003 »

Other than "how small can you make your BASIC listing" competitions, there are times when it is a good idea to use all the NOT / SGN / INT PI and VAL tricks outside of trying to cram a bare-bones listing into a 1K ZX81. I do it all the time when making CSSCGC entries or WOOT! programs, because inevitably they'll contain UDGs and/or custom character sets, and (since 2020) a couple of kilobytes of machine code. If I'm using BASin, these need to be in the program listing, and hordes of DATA statements with floating-point values where they don't need to be (because they're all integers between 0 and 255) eat memory faster than Nikocado Avocado.

After deciding that [url=https://spectrumcomputing.co.uk/entry/3 ... OT_EDITION]the original Spectrum port of Illuminati[url] should be suitable for the 16K model, which has considerably less usable memory than a 16K ZX81, I had to convert the entire listing to NOT / SGN / INT PI and a load of VALs just to get it to fit into the 9K or so available. The total memory used for the BASIC listing was 7,492 bytes (with 568 bytes of machine code loaded externally); take out all the ZX81 memory-saving techniques and the listing - for an otherwise identical program - grows to 8,438 bytes, so even though there was space in the 16K model to accommodate the listing and machine code, there wasn't enough usable memory remaining to run it. And that's for a listing with no DATA statements (not too surprising, given its ZX81 origins) and with the number arrays already converted to bytes and PEEKs.

There's also little reason to dread the hard slog of typing out all those VALs. If I need to get a character set or machine code from another program that's already in .TZX or .TAP format (or .MDR, .DSK, .TRD, .MGT, .SCL, .OPD, .D80, .WDR and so on...), I'll load it into Fuse and do something like this:

10 FOR n=startaddress to endaddress
20 LPRINT "VAL """;PEEK n;""",";
30 NEXT n

Or, to make it really clear:
20 LPRINT "VAL ";CHR$ 34;PEEK n;CHR$ 34;",";

All I need to do from here is retrieve fuseprintout.txt, remove all the carriage returns, insert lines and DATA commands, remove any marauding commas from the end of a line, and paste the DATA listing into BASin with a quick and dirty loop to POKE it all in place.
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
1024MAK
Bugaboo
Posts: 3123
Joined: Wed Nov 15, 2017 2:52 pm
Location: Sunny Somerset in the U.K. in Europe

Re: Memory saving in BASIC - summary table

Post by 1024MAK »

A line 1 REM is useful for storing data in. But as always, any control characters will mess up the automatic or manual listing...
It's certainly more space efficient than data statements that contain numbers.

Or you could be clever and put the REM at the end of the program, but a bit more maths is needed to find its location in memory.

Mark
:!: Standby alert :!:
“There are four lights!”
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb :dance
Looking forward to summer later in the year.
Post Reply