LB Booster
« about GOSUBs »

Welcome Guest. Please Login or Register.
Apr 1st, 2018, 04:07am



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
We apologize Conforums does not have any export functions to migrate data.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

Thank you Conforums members.
Speed up Liberty BASIC programs by up to ten times!
Compile Liberty BASIC programs to compact, standalone executables!
Overcome many of Liberty BASIC's bugs and limitations!
LB Booster Resources
LB Booster documentation
LB Booster Home Page
LB Booster technical Wiki
Just BASIC forum
BBC BASIC Home Page
Liberty BASIC forum (the original)

« Previous Topic | Next Topic »
Pages: 1 2  Notify Send Topic Print
 hotthread  Author  Topic: about GOSUBs  (Read 1498 times)
tsh73
Full Member
ImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 210
xx about GOSUBs
« Thread started on: Jun 7th, 2016, 7:18pm »

They are came up as a side-topic in reply 55 at this thread
Card graphics not sticking
And I thought matter is rested.
But alas today I saw this on LB forum:
Quote:
Kind regards and may all your Gosubs Return

so. If anything this is a "redeeming feature" for me.

May the Source be with you! wink))
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx Re: about GOSUBs
« Reply #1 on: Jun 7th, 2016, 9:36pm »

on Jun 7th, 2016, 7:18pm, tsh73 wrote:
But alas today I saw this on LB forum: "Kind regards and may all your Gosubs Return"

I can't see that comment (probably in a part of the forum I'm not allowed to read) but if it was a signature I don't think it is necessarily recommending the use of GOSUBs, but rather that if you do use them you'd better hope that they RETURN eventually!

Actually there's a serious point here. If, for example due to a convoluted program, the GOSUB never RETURNs (maybe it ends up at a WAIT) the result will be a memory leak that eventually, if the program is left running for long enough, will cause all the memory to be exhausted and a catastrophic failure.

If you use CALL rather than GOSUB it's less likely that a problem of this sort would go unnoticed, if only because you have to think more carefully about program structure.

Richard.
« Last Edit: Jun 7th, 2016, 9:37pm by Richard Russell » User IP Logged

Mystic
Junior Member
ImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 53
xx Re: about GOSUBs
« Reply #2 on: Jun 7th, 2016, 10:05pm »

WOW! After reading that I feel like an idiot.

My programs are all about the GOSUBs. Throwback from TRS80, C64, Amiga QBASIC days I guess. LOL

Time to research more on CALLS and get my programming shit together I guess. sad
« Last Edit: Jun 7th, 2016, 11:24pm by Mystic » User IP Logged

- Rick
Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx Re: about GOSUBs
« Reply #3 on: Jun 8th, 2016, 08:22am »

Here's an example of the sort of thing that can happen by accident. Try running the program in the LBB debugger and watch the 'Stack usage' figure:

Code:
    timer 10, [tick]
    wait
    
[tick]
    gosub [handler]
    wait
    
[handler]
    ' do something
    wait 

Of course with such a small program the problem is obvious, but in a large or convoluted program it could easily go unnoticed.

If I run that same program in the LB 4.04 debugger it doesn't give me any indication that anything is wrong.

Richard.
User IP Logged

Mystic
Junior Member
ImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 53
xx Re: about GOSUBs
« Reply #4 on: Jun 9th, 2016, 3:55pm »

I've now removed all GOSUBS from one of my main programs, and replaced them with SUB's or FUNCTION's as needed.

I have two more larger ones to tackle. From now on I will tread lightly around the GOSUB and use these alternatives.

Apparently an old dog CAN learn new tricks! smiley

Thanks Richard!
User IP Logged

- Rick
RobM
Junior Member
ImageImage


member is offline

Avatar




PM


Posts: 91
xx Re: about GOSUBs
« Reply #5 on: Jun 9th, 2016, 8:02pm »

Just ran the following program on my cabinet program. I have 9,198 gosub commands. :o

I seem to remember a discussion about the speed of gosubs, subs and functions back when I started with LB. Carl said gosubs were faster in general because subs & functions need to allocate memory each time they were used, whereas gosubs do not. Wonder if the same is true in LBB?

Code:
    filedialog "Open text file", "*.bas", fileName$
    open fileName$ for input as #1
    while not(eof(#1))
      line input #1, temp$
        if instr(temp$,"gosub")>0 then count=count+1
      wend
    print count
    close #1
    end
 
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx Re: about GOSUBs
« Reply #6 on: Jun 9th, 2016, 9:41pm »

on Jun 9th, 2016, 8:02pm, RobM wrote:
I seem to remember a discussion about the speed of gosubs, subs and functions back when I started with LB. Carl said gosubs were faster in general because subs & functions need to allocate memory each time they were used, whereas gosubs do not. Wonder if the same is true in LBB?

It's not difficult to do the test. Here is the program I used:

Code:
    t0 = time$("ms")
    for i = 1 to 200000
    next
    t1 = time$("ms")
    for i = 1 to 200000
      gosub [MySub]
    next
    t2 = time$("ms")
    for i = 1 to 200000
      call MySub
    next
    t3 = time$("ms")
    print "Total time taken for GOSUBs = "; (t2 - t1) - (t1 - t0) ; " ms"
    print "Total time taken for CALLs =  "; (t3 - t2) - (t1 - t0) ; " ms"
    end
    
[MySub]
    return
         
sub MySub
end sub 

Results on my PC:

LBB v3.05:
Total time taken for GOSUBs = 114 ms
Total time taken for CALLs = 56 ms


LB v4.04:
Total time taken for GOSUBs = 1328 ms
Total time taken for CALLs = 4232 ms


So in LBB CALL is roughly twice as fast as GOSUB, and LBB's CALL is about seventy-five times faster than LB's CALL!

But of course the benefit will be much reduced once the subroutines actually contain some useful code. Also, it's arguably unfair not to pass any parameters to the SUB; passing just a single parameter makes CALL slower than GOSUB.

In most practical cases I would expect the time taken by the code within the subroutine to dominate the time taken in the actual GOSUB or CALL, so speed should not be an issue in deciding which to use.

Richard.
« Last Edit: Jun 10th, 2016, 09:20am by Richard Russell » User IP Logged

RobM
Junior Member
ImageImage


member is offline

Avatar




PM


Posts: 91
xx Re: about GOSUBs
« Reply #7 on: Jun 9th, 2016, 9:55pm »

Similar results here.

LBB 3.03:
Total time taken for GOSUBs = 35 ms
Total time taken for CALLs = 13 ms


LB 4.04:
Total time taken for GOSUBs = 546 ms
Total time taken for CALLs = 1965 ms
« Last Edit: Jun 9th, 2016, 9:55pm by RobM » User IP Logged

Jack Kelly
Full Member
ImageImageImage


member is offline

Avatar




Homepage PM

Gender: Male
Posts: 106
xx Re: about GOSUBs
« Reply #8 on: Aug 2nd, 2016, 09:46am »

I've been looking at the code for Freeform 4. It contains about 68 gosub subroutines -- ones starting with a label and ending with a RETURN. 233 GOSUB calls are made to these subroutines. To convert all the gosubs to calls in this program would involve declaring possibly hundreds of global variables. Are there any downsides to global variables? Could this be a redeeming factor in using a GOSUB?
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx Re: about GOSUBs
« Reply #9 on: Aug 2nd, 2016, 1:05pm »

on Aug 2nd, 2016, 09:46am, Jack Kelly wrote:
Are there any downsides to global variables? Could this be a redeeming factor in using a GOSUB?

The important question is: "what are those global variables used for?". With a traditional GOSUB..RETURN, global variables are the only way to pass values into a subroutine (inputs) or return values back from a subroutine (outputs). When replacing the GOSUB with a CALL any global variables used solely for those purposes should be substituted by the appropriate 'modern' equivalents: parameters for inputs and BYREF parameters (or the value returned from a FUNCTION) for outputs.

Having substituted the global variables used for inputs and outputs, any other global variables still accessed from within the subroutine will, as you say, have to be declared as GLOBAL. If the program is well structured, there should be relatively few such variables and they should be 'inherently' global in scope (i.e. making them GLOBAL should actually enhance the readability of the code rather than the opposite).

However if there are global variables accessed within the subroutine that are neither 'inputs', 'outputs' nor of genuinely 'global scope' then the program is poorly structured. You cannot convert a poorly structured program into a structured program just by replacing GOSUBs with CALLs, so in that case you should probably give up the struggle and declare the program to be beyond redemption!

Richard.
« Last Edit: Aug 2nd, 2016, 2:08pm by Richard Russell » User IP Logged

joker
Global Moderator
ImageImageImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 157
xx Re: about GOSUBs
« Reply #10 on: Aug 2nd, 2016, 1:46pm »

Oh Richard, your succinct replies are beyond reproach! cheesy
User IP Logged

BrianM
New Member
Image


member is offline

Avatar




PM


Posts: 15
xx Re: about GOSUBs
« Reply #11 on: Aug 2nd, 2016, 4:10pm »

Gosubs are not completely redundant as they can be used inside subroutines and functions. The advantage in using a gosub over using a subroutine or function is that the gosub code "sees" the same variables as the calling sub or function and so no extra global variables are required to share data. The disadvantage is that you cannot use parameters. In certain situations this can result in a simpler code structure.

This is similar to internal and nested subroutines available in other languages.

I have found that in LBB that the labels for the gosub code must be unique throughout the program and not just in the enclosing subroutine or function. This is not the case in Liberty Basic.

Brian Matthews
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx Re: about GOSUBs
« Reply #12 on: Aug 2nd, 2016, 4:51pm »

on Aug 2nd, 2016, 4:10pm, BrianM wrote:
I have found that in LBB that the labels for the gosub code must be unique throughout the program and not just in the enclosing subroutine or function. This is not the case in Liberty Basic.

That is not correct, in general, as the simple test program below demonstrates:

Code:
    gosub [label1]
    call mysub
    call anothersub
    gosub [label1]
    stop
    
[label1]
    print "At [label1] in the main program"
    return

sub mysub
    gosub [label1]
    exit sub
[label1]
    print "At [label1] in sub mysub"
    return
end sub    

sub anothersub
    gosub [label1]
    exit sub
[label1]
    print "At [label1] in sub anothersub"
    return
end sub 

You can probably contrive a situation in which it won't work, for example by placing the destination for the outer GOSUB after rather than before the SUBs, but if you follow the recommendation to place all SUBs and FUNCTIONs at the end of the program that situation won't arise.

Richard.
« Last Edit: Aug 2nd, 2016, 4:54pm by Richard Russell » User IP Logged

BrianM
New Member
Image


member is offline

Avatar




PM


Posts: 15
xx Re: about GOSUBs
« Reply #13 on: Aug 2nd, 2016, 5:07pm »

This is my test program that works in LB but not LBB. I can't see an error.
Code:
call mysub1
call mysub2
end

sub mysub1
for i = 1 to 5
    gosub [internal_sub]
next

exit sub

[internal_sub]
    print "internal sub(mysub1)",i
    return

end sub

sub mysub2
for i = 1 to 5
    gosub [internal_sub]
next

exit sub

[internal_sub]
    print "internal sub(mysub2)",i
    return

end sub
 


Brian Matthews
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx Re: about GOSUBs
« Reply #14 on: Aug 2nd, 2016, 5:35pm »

on Aug 2nd, 2016, 5:07pm, BrianM wrote:
This is my test program that works in LB but not LBB. I can't see an error.

That's a quite separate issue, caused by you including an 'illegal' character (an underscore) in your labels. This is what the LB Help File has to say about label names: "The label can be either a traditional line number or a branch label in the format [branchLabel] where the branch label name can be any upper/lowercase letter combination. Spaces and digits are not allowed".

It's not as precise as I would like, but I interpret "any upper/lowercase letter combination" as not permitting the use of an underscore - after all underscores definitely aren't allowed in variable names (except Windows Constants) and it's uncommon for different rules to apply.

If you remove the underscores from your label names (or substitute a character which is legal in a variable name like a dot) the program works as expected:

Code:
call mysub1
call mysub2
end

sub mysub1
for i = 1 to 5
    gosub [internalsub]
next

exit sub

[internalsub]
    print "internal sub(mysub1)",i
    return

end sub

sub mysub2
for i = 1 to 5
    gosub [internalsub]
next

exit sub

[internalsub]
    print "internal sub(mysub2)",i
    return

end sub 

Richard.
User IP Logged

Pages: 1 2  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls