High VARS = slower code?
High VARS = slower code?
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?
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?
Re: High VARS = slower code?
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
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
Re: High VARS = slower code?
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.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?
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.
Re: High VARS = slower code?
You've really piqued my interest
Any chance of having a look at the 2 programs for a compare-and-contrast?
C
Any chance of having a look at the 2 programs for a compare-and-contrast?
C
Re: High VARS = slower code?
I was hoping you'd never ask as it's my embarrassingly basic attempt to write something in BASIC. I'm a total noobsirmorris wrote:You've really piqued my interest
Any chance of having a look at the 2 programs for a compare-and-contrast?
C
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
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.
Re: High VARS = slower code?
Except 35% slower?
You say the larger program didn't even have to run in order to witness the slowdown?
C
You say the larger program didn't even have to run in order to witness the slowdown?
C
Re: High VARS = slower code?
Could it be because the DFILE is pushed past 32767?
Bill H
Bill H
Re: High VARS = slower code?
If the code is identical, then DFILE of both programs should sit at the same location in memory (please check that).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.
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
http://zx81.ddns.net/ZxTeaM
Re: High VARS = slower code?
Yes.sirmorris wrote:You say the larger program didn't even have to run in order to witness the slowdown?
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
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.
Re: High VARS = slower code?
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
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