High VARS = slower code?

Anything Sinclair ZX Basic related; history, development, tips - differences between BASIC on the ZX80 and ZX81
alowe
Posts: 19
Joined: Sun Aug 26, 2012 2:58 pm

High VARS = slower code?

Post by alowe »

Using EightyOne, I have two BASIC programs, with identical code and identical configuration (memory amount, speed, etc).
One runs 32% slower than the other.

The only difference I can see is, for the quicker one VARS is 18,219, and for the slower one VARS is 43,198.

Has this introduced a significant enough address range difference between the BASIC program and the variables it is accessing to explain the slowdown?
sirmorris
Posts: 2811
Joined: Thu May 08, 2008 5:45 pm

Re: High VARS = slower code?

Post by sirmorris »

Interesting. I've never heard of this before. AFAIK the memory location is irrelevant. How are the vars pushed way up there though? Do you define a honking great array to push the vars above 32k?

The vars are searched in a linear fashion each time one is accessed; there is no caching of data addresses so the ordering of the vars is crucial; most commonly used ones should be defined first so the search takes less time. The size (in bytes) of the variables themselves won't contribute dramatically, as it's simply a case of adding the size to a pointer each time, but the number of variables would. More vars = longer to search.

Avoid re-using numeric types as FOR indices as the memory will be shuffled around; I is a common variable name but the way that ZX81 stores its variables in memory means that I used as a number is different from I as used in a FOR statement. If you define I as something inside a loop then later re-define it as a FOR type then all the variables (including your huge array, if one's present) will be moved around in memory, possibly resulting in your slowdown.

One way to check in EO is to bring up the memory inspector and regularly break into the program - using the debugger STOP button rather than space/break. The memory inspector will show all locations altered since the last stop in red. You could also consult the ROM disassembly and locate the shuffle routine...

C
alowe
Posts: 19
Joined: Sun Aug 26, 2012 2:58 pm

Re: High VARS = slower code?

Post by alowe »

sirmorris wrote:Interesting. I've never heard of this before. AFAIK the memory location is irrelevant. How are the vars pushed way up there though? Do you define a honking great array to push the vars above 32k?
The 1st program has the test code on its own, so is very small. The 2nd program has the test code at the beginning of a listing with a larger program after it that isn't run, hence VARS being much higher.

I'd written some code to test a possibility, and when it worked okish, pasted it into the larger program, only to find it behaved quite differently. I eliminated any interference from the rest of the code by not running it, by dimensioning the array used first (only 232 bytes really), and by doing a CLS before running it incase the contents of the screen somehow made a difference. I even renamed the array from Z$ to A$ (as in my test code) incase the name itself had an effect.

After doing all of this, the test code takes 19 seconds but the same exact code (as far as I can tell), takes 25 seconds to run in the larger program. I never considered the rest of the code in the larger program to be significant because it isn't run, but then it does effect VARS.

In the end I'll just not incorporate the code as it spoils the game I'm writing. Still, it's worrying that a larger program runs slower not by logic of its design, but simply by its size. At the moment I've gone completely back to scratch and am redesigning and rewriting the whole project (in Notepad) to try and squeeze it into as little code space as possible without compromising the original idea.


PS
Another idea I have is that the D_FILE in the larger program is also in a different memory space. I had to do the extra-large line workaround to push past it. Should this have an effect on screen update speed? The code I'm running is in SLOW by nature, so screen update speed is a factor.
sirmorris
Posts: 2811
Joined: Thu May 08, 2008 5:45 pm

Re: High VARS = slower code?

Post by sirmorris »

You've really piqued my interest :)

Any chance of having a look at the 2 programs for a compare-and-contrast?

C
alowe
Posts: 19
Joined: Sun Aug 26, 2012 2:58 pm

Re: High VARS = slower code?

Post by alowe »

sirmorris wrote:You've really piqued my interest :)

Any chance of having a look at the 2 programs for a compare-and-contrast?

C
I was hoping you'd never ask as it's my embarrassingly basic attempt to write something in BASIC. I'm a total noob :oops:

Code: Select all

1 LET F=3
5 FAST
6 DIM Y(18)
7 DIM X(18)
10 DIM S$(14,16)
20 FOR R=1 TO 14
30 LET S$(R)="                " ' inverted
40 NEXT R
60 FOR R=1 TO 18
70 LET X=INT (RND*640)+1
80 LET Y(R)=INT (X/32)
90 LET X(R)=INT ((X-Y(R)*32)/2)+1
92 LET Y(R)=INT (Y(R)/1.43)+1
95 NEXT R
96 SLOW
100 FOR N=1 TO F*2
105 FOR R=1 TO 18
115 LET X=X(R)
120 LET X(R)=(X<5)*(X+12)+(X>4)*(X-4)
125 LET S$(Y(R),X)=" " ' inverted
130 LET S$(Y(R),X(R))="." ' inverted
150 NEXT R
155 PRINT AT 1,8;S$(1);AT 2,8;S$(2);AT 3,8;S$(3);AT 4,8;S$(4);AT 5,8;S$(5);AT 6,8;S$(6);AT 7,8;S$(7);AT 8,8;S$(8);AT 9,8;S$(9);AT 10,8;S$(10);AT 11,8;S$(11);AT 12,8;S$(12);AT 13,8;S$(13);AT 14,8;S$(14);
160 NEXT N
All it does is store what I want to output in an array, then moves randomly placed stars ("."s) left a bit, then updates and repeats.
I know there's probably a million better ways to do it but it's a learning exercise. I'm just starting to convert all my number arrays to string arrays for example.

The big PRINT at 155 chucks it out all in one go, rather than step through a loop which I found made it much slower.
No doubts there's tricks by limiting the screen display size, peeking, poking and assembler, but I wanted to write my program purely in BASIC before trying to hack it into something more abstract and alien.

The larger program has been abandoned to the scrap heap. If you pasted this into the beginning of a large program with VARS over 32k, dimensioning everything used in it first and making sure the screen was cleared it'd be the same as I've tested it.
sirmorris
Posts: 2811
Joined: Thu May 08, 2008 5:45 pm

Re: High VARS = slower code?

Post by sirmorris »

Except 35% slower?
You say the larger program didn't even have to run in order to witness the slowdown?

C
Bill H
Posts: 163
Joined: Sat Nov 27, 2010 6:05 pm

Re: High VARS = slower code?

Post by Bill H »

Could it be because the DFILE is pushed past 32767?

Bill H
User avatar
siggi
Posts: 990
Joined: Thu May 08, 2008 9:30 am
Location: Wetterau, Germany
Contact:

Re: High VARS = slower code?

Post by siggi »

alowe wrote:Using EightyOne, I have two BASIC programs, with identical code and identical configuration (memory amount, speed, etc).
One runs 32% slower than the other.

The only difference I can see is, for the quicker one VARS is 18,219, and for the slower one VARS is 43,198.
If the code is identical, then DFILE of both programs should sit at the same location in memory (please check that).
After CLS the d-file is fully expanded, so VARS of both program should also sit (immediately befind DFILE) at the same location!
So IMHO the system variables of the slower program are corrupted. This may lead to a crash or some other strange effects ....

Siggi
My ZX81 web-server: online since 2007, running since dec. 2020 using ZeddyNet hardware
http://zx81.ddns.net/ZxTeaM
alowe
Posts: 19
Joined: Sun Aug 26, 2012 2:58 pm

Re: High VARS = slower code?

Post by alowe »

sirmorris wrote:You say the larger program didn't even have to run in order to witness the slowdown?
Yes.

I have a feeling it's something dumb I've done. Not the ZX81 architecture or EightyOne.
Following the MemoPak32k doc, when VARS got close to 32k, I entered in a line with LET ZERO=+0+0+0... (100 times) to push the DFILE past 32k.
After programming for a while longer, and not really wanting this ugly LET ZERO line in there, I deleted it to see if it still worked. I'm now wondering if this was wise as the doc never said to do this.

Anyway, I've re-written my little noobish attempt, and managed to get the time down to 4 seconds. So, now even if it adds 35%, it'll still be less than 6 seconds, which is a lot better than the original 19.

Code: Select all

1 LET F=3
5 FAST
6 DIM Y(18)
7 DIM X(18)
8 LET D$="                " ' inverted
10 DIM S$(224)

15 PRINT AT 1,8;
20 FOR R=0 TO 13
30 LET S$(R*16+1 TO (R+1)*16)=D$
35 PRINT D$,TAB 8;
40 NEXT R

50 FOR R=1 TO 18
60 LET S$(INT (RND*224)+1)="." ' inverted
70 NEXT R

80 LET X=F*4
90 SLOW
100 FOR N=1 TO X
110 PRINT AT 1,8;S$(1 TO 16),TAB 8;S$(17 TO 32),TAB 8;S$(33 TO 48),TAB 8;S$(49 TO 64),TAB 8;S$(65 TO 80),TAB 8;S$(81 TO 96),TAB 8;S$(97 TO 112),TAB 8;S$(113 TO 128),TAB 8;S$(129 TO 144),TAB 8;S$(145 TO 160),TAB 8;S$(161 TO 176),TAB 8;S$(177 TO 192),TAB 8;S$(193 TO 208),TAB 8;S$(209 TO 224);
120 LET S$=S$(2 TO 224)+S$
130 NEXT N
The main project is still in notepad form and currently sits at 740 lines, with still over 100 lines yet to add.
I've used strings instead of number arrays where practical, but it seems that the extra code to extract and manipulate them sometimes makes the program larger in total (program+variables), so after testing I'm going to go through several repetitions of reduction to reduce the size to its optimum.

It's only the 2nd project I've done on ZX81, so a good test for a beginner.
alowe
Posts: 19
Joined: Sun Aug 26, 2012 2:58 pm

Re: High VARS = slower code?

Post by alowe »

Sorry to double post :?

Well, I've entered the code from notepad. Took 15 hours over 2 days. As before the screen started flickering as VARS neared 32k, did the LET ZERO= line, which was in the middle of a time critical loop so had to delete it again after. I figure once DFILE is induced to change to 32k it doesn't matter since it'll always be used to decide where the screen is displayed from.

There is a slowdown, and not just when running code. Entering code in FAST has a noticeable slowdown. I guess the Zeddy has to reorganise it all every time there's a change. Since the code alone is about 30k now and still rising, I'm not surprised.

Ok, well, unless anyone wants to add more, I'll just continue and keep finding ways to make the code run faster so that any slowdown isn't too noticeable. Due to the nature of the game I'm writing, it'll always be large so can't cut it too ruthlessly without affecting the overall feeling of it. Maybe I'll make a lite version later :)
Post Reply