'on goto'; return problem

moorea21

Senior Member
I wrote this instead of a 'case select' block, to speed up execution.
Code:
For b5 = 1 to 8
  on b5 goto cL0, cL1, cL2, cL3, cL4, cL5, cL6, cL7, cL8	'cL0 is dummy
next b5
b5 = 0					'reset b5 for use in main

cL0:
cL1: w1 = $0100 : gosub sendToLedsW1
cL2: w1 = $0200 : gosub sendToLedsW1
cL3: w1 = $0300 : gosub sendToLedsW1
cL4: w1 = $0400 : gosub sendToLedsW1
cL5: w1 = $0500 : gosub sendToLedsW1
cL6: w1 = $0600 : gosub sendToLedsW1
cL7: w1 = $0700 : gosub sendToLedsW1
cL8: w1 = $0800 : gosub sendToLedsW1

sendToLedsW1: return
These labels will also be called at other points in the code, from 'on goto' lines identical to the one above.

I was expecting that having completed the code in, for instance, label cL1, it would return focus to the for/next loop, but of course it just continues down the page to cL2, etc; which defeats the object of using 'on goto.' I tried putting a 'return' line at the end of each label's code, but I get a 'stack underflow' message.

As the 'on goto' command also occurs at other points in the code, (at which point I only want it to execute 1 line) I don't want to give it a label to return to.

How do I get this to return to whatever line is just after the specific 'on goto' line that called it?
 

moorea21

Senior Member
OK, to be more specific, seeing as I was trying to compare some code that doesn't work against some that does (duh)

Which of these would execute faster?

Code:
b5 =2
If b1 <> b5 then
  on b5 gosub cL0, cL1, cL2, cL3, cL4, cL5, cL6, cL7
End If
gosub sendToLedsW1

cL0:
cL1: w1 = $0100 : gosub sendToLedsW1: return
cL2: w1 = $0200 : gosub sendToLedsW1: return
cL3: w1 = $0300 : gosub sendToLedsW1: return
cL4: w1 = $0400 : gosub sendToLedsW1: return
cL5: w1 = $0500 : gosub sendToLedsW1: return
cL6: w1 = $0600 : gosub sendToLedsW1: return
cL7: w1 = $0700 : gosub sendToLedsW1: return

sendToLedsW1: return
Or
Code:
b5 = 2
If b1 <> b5 then
  on b5 goto cL0, cL1, cL2, cL3, cL4, cL5, cL6, cL7
  rowCleared:
End If
gosub sendToLedsW1

cL0: goto rowCleared
cL1: w1 = $0100 : gosub sendToLedsW1: goto rowCleared
cL2: w1 = $0200 : gosub sendToLedsW1: goto rowCleared
cL3: w1 = $0300 : gosub sendToLedsW1: goto rowCleared
cL4: w1 = $0400 : gosub sendToLedsW1: goto rowCleared
cL5: w1 = $0500 : gosub sendToLedsW1: goto rowCleared
cL6: w1 = $0600 : gosub sendToLedsW1: goto rowCleared
cL7: w1 = $0700 : gosub sendToLedsW1: goto rowCleared

sendToLedsW1: return
 

Buzby

Senior Member
Code:
for b5 = 1 to 8
  w1 = $0100 * b5
  gosub sendToLedsW1
next b5
I think this does what you want, but without any go-stuff.

It works because in your code you set w1 to a value which is the same as $0100 times b5, so just do that once and you don't need 'on goto' at all.
 
Last edited:

oracacle

Senior Member
as it doesn't seem to have been pointed out, to return you need to use a gosub. There are restrictions on using this and should be used with caution to stop stack overflow.
gosub stores a return address so that it know where to go back to. goto does not do this as far as I know and understand and as a result the return at the bottom of you code will just be ignored or "drop through"
 

moorea21

Senior Member
Thanks both, and double thanks Buzby, thats exactly the sort of thing I looked for in other areas of code, but I didnt think of doing it here. Getting a bit tired I think, time for a break.

Just for the record though, is my gosub code, or my goto code likely to be faster to execute?
 

techElder

Well-known member
Its unlikely that they would work well. The goto routine is the classic definition of "spaghetti code."

I don't have time to rebuild them, but I can see where they could be optimized (other than eliminated by Buzby's version.)
 

hippy

Technical Support
Staff member
Would that execute faster or slower than 'on goto'?
Yes it would. ... :D.
"Yes please" is often my answer to "would you like tea or coffee?" :)

Ignoring the better options suggested; as noted it should be GOSUB ...
Code:
For b5 = 1 to 8
  on b5 [b]gosub[/b] cL0, cL1, cL2, cL3, cL4, cL5, cL6, cL7, cL8	'cL0 is dummy
next b5
But for reflection and educational enjoyment there's another option to consider ...

Code:
For b5 = 1 to 8
  gosub clX
next b5

clX:
  on b5 goto cL0, cL1, cL2, cL3, cL4, cL5, cL6, cL7, cL8	'cL0 is dummy
The GOSUB is to 'clX:' but the RETURN to take it back will be the ones in the 'cl0:' through 'cl8:' routines.
 

moorea21

Senior Member
That would be my kind of hack!
Seeing as I'm hoping to learn whether in general gosub is faster than goto (or a mixture of both, as above, or even a macro...) Is there some general rule of thumb about this, that I can apply if I want code that executes as fast as possible?
 

techElder

Well-known member
RULE-OF-THUMB

Generally speaking, the fewer characters you have, the faster it will be.

Keep optimizing your code by thinking, "How can I reduce the number of statements (characters) in this code and make it perform the same function?"

Put your finger on the screen and follow your code path by pointing with your finger. If your finger is wiggling really fast, then your code is probably as fast as it can be. :D





PS. Yes, I know I opened up a can of worms, and someone will eventually be offended! :D
 

moorea21

Senior Member
Okay, thanks.
So it's number of characters rather than 'avoid using x an y commands if you want fast execution' then?
If so, that's simpler than I expected. Which is something I dont get to say on here very often.
 

techElder

Well-known member
Not exactly that, but yeah. You asked about a "rule of thumb".

If you're reducing the number of commands a program has to execute, then naturally its going to run faster (and you're reducing the character count.)

Of course, at some point reduction will produce nonfunctional code. :D
 

moorea21

Senior Member
Yep, rules of thumb so far are:
1) Brevity
2) Avoid spaghetti
3) Write a bit, test, refine, write some more, repeat
 

lbenson

Senior Member
Absolutely on #3. Try to avoid writing all at one time big chunks of code in which different things are done--makes it much harder to debug.

Disregard #1 when writing comments.
 
Last edited:

AllyCat

Senior Member
Hi,

Disregard #1 when writing comments.
And also when creating symbol names! But I do try to keep the names moderately short so that I can fit more into each program line. ;) Or more particularly, to leave plenty of space for a clear (useful!) comment after each instruction.

A GOTO (or even two) is significantly faster than a GOSUB ... RETURN (actually it's the Return that is slow), but using Subroutines is likely to be much better for writing a clear and efficient program.

The ON ... GOTO construct can be up to 5 times faster than a sequence of IF .. GOTOs, or SELECT ... CASEs, etc. But AFAIK the ON .. GOSUB just uses a GOSUB tacked onto each label in an ON ... GOTO list.

Occasionally it's necessary to use a few "Programming tricks" for maximum speed. But usually the "fastest" code will be produced by structuring the program (flow) properly.

Cheers, Alan.
 
Top