Yesterday I started to look into why Michael Fernie's Pop The Lock lock drawing was so slow.
-=-=-
It's an odd one, because he's barely drawing anything, really, just a whole bunch of lines in a circle.
This is roughly the bit of the code that's slowing down.
Graphics 512,512,1
LockX=256:LockY=256
Repeat
CLS
lap=Mills()
for m=0 to 20 // Do it multiple times to stress out the system
for a=0 to 360 step 9
ss=Sin(a)
cc=Cos(a)
dx=(ss*105)+LockX
dy=(0-(cc*105))+LockY
Line dx+(ss*8), dy-(cc*8), dx+ss, dy-cc
next
next
Text 256,256,Mills()-lap,1
Flip
Forever
So I opened up the drawing code and tweaked what I could.
I struggled for AGES to figure out why that particular draw routine was running slowly, until thinking to myself .. "Maybe it's not the draw routine...?"
Graphics 512,512,1
LockX=256:LockY=256
Repeat
CLS
lap=Mills()
for m=0 to 20 // Do it multiple times to stress out the system
for a=0 to 360 step 9
Line (Sin(a)*105)+LockX, (0-(Cos(a)*105))+LockY, (Sin(a)*113)+LockX, (0-(Cos(a)*113))+LockY
next
next
Text 256,256,Mills()-lap,1
Flip
Forever
Here it is again.
Does the same thing, but this time everything inside the draw loop is reduced down to a single line.
It seems that most of the slowdown is because the interpreter has to run through so much code, and THAT is what's slowing it down.
In Michael's code, there are 41 "tokens" in the loop.
In the single-line code, there are only 29 tokens.
It's this difference in the script that slows it down.
Which made me wonder... How could I optimise THAT?!
So I dug deep into the JSE parser.
First I added a secondary shorter loop that takes over whenever something small happens.
eg, if the token is just a number, it can quickly just say "this is a number.. carry on.."
Maths is also a short loop, too.
Variables now act differently to commands, and should also hopefully be a little quicker as a result.
The Big Task
Next up, something I've been putting off doing.
The switch for the command list is all written using "Strings".
People keep telling me integers are quicker, but experiments were showing little difference on my MacBook. I also did my test on various other systems with little to no difference.
But.. Guess it needs doing!!
This took about an hour to get done.
For every single command in the script, I needed to jot down what the command was, give it a unique number, place both of these into an array, and put the number back into the Switch loop.
Carefully does it, because one single mis-type, of either the command name or the unique number, would break EVERYTHING..
I went through, and by the halfway point was wishing I'd coded something to do this for me.
But I carried on regardless, line by line, command by command.
Eventually I reached the end and got around to adding the code to work with numbers instead of strings.
Now the parser flicks through the command list, and replaces known commands with numbers as it goes.
I've now uploaded the newer version and the results are...
...
odd.
On most browsers it seems a little bit quicker. Not much, just a teensy bit.
On desktop MacOS Safari, it's gotten slower. And I'm baffled as to why that is.
If anything, I expected it to run at the same speed, not slower!!
I'll have to keep tweaking the thing, I think.
For the most-part, you should find your scripts now run (as has been the case for most of this month) just a teensy bit faster.
Meanwhile...
For realtime comparisons between the multi-line and single-line code from earlier, here's a nice script that shows both methods in one, along with all the tokens being numbered.
Top number = the multi-line code, Bottom number = the single-line version.
// Methodology Test
// by Jayenkai with some of Michael Fernie's code
// Created 2021/7/16
Graphics 512,512,1
LockX=256:LockY=256
m0=0:m1=0
Repeat
CLS
lap=Mills()
Method=0
if Mills() mod 2000<1000 then Method=1
for m=0 to 20 // Do it multiple times to stress out the system
if Method==0
for a=0 to 360 step 9
ss=Sin(a)
// 1 2 3 4
cc=Cos(a)
// 5 6 7 8
dx = (ss * 105) + LockX
// 9 10 11 12 13 14 15
dy = (0 - (cc * 105) ) + LockY
// 16 17 18 19 20 21 22 23 24
Line dx + ( ss * 8), dy - (cc * 8), dx + ss, dy - cc
// 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
next
endif
if Method==1
for a=0 to 360 step 9
Line (Sin(a) * 105) + LockX, (0 - (Cos( a) * 105)) + LockY, (Sin( a ) * 113) + LockX, (0 - (Cos( a )* 113)) + LockY
// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
next
endif
next
if Method==0 then m0=Mills()-lap
if Method==1 then m1=Mills()-lap
Text 256,256-32,m0,1
Text 256,256+32,m1,1
Text 256,256,Method,1
Flip
Forever