[Gambas-user] Are GoSubs efficient?
nando_f at nothingsimple.com
nando_f at nothingsimple.com
Mon Apr 22 23:51:12 CEST 2019
I have been using GOSUB as a common code subroutine when I don't need to pass variables.
It's almost like having an anonymous function using the existing local vars.
It works much faster overall especially if you do a lot them and time matters.
I also use them for making PDF's in a function to do little repeated work.
They also help me with user input cleanup.
I believe there is a place for their use.
I normally place/write them at the end of a function
---------- Original Message -----------
From: Cedron Dawg <cedron at exede.net>
To: user <user at lists.gambas-basic.org>
Sent: Mon, 22 Apr 2019 16:41:46 -0400 (EDT)
Subject: Re: [Gambas-user] Are GoSubs efficient?
> Thanks, this was really helpful and extremely informative.
>
> ----- Original Message -----
> From: "Tobias Boege" <taboege at gmail.com>
>
> At the bytecode level, GoSub compiles to a single instruction, whereas
> a call is at least two. This nonsensical piece of code
>
> Public Function f(a As Integer, b As Integer) As Integer
> _Next:
> Dec a
> GoSub _Next
> f(a, b - 1)
> End
>
> for example becomes
>
> 0000 : 02FE PUSH PARAM -2
> 0001 : AFFF ADD QUICK -1
> 0002 : 0AFE POP PARAM -2
> 0003 : 2300 FFFB GOSUB 0000
> 0005 : B803 PUSH FUNCTION f
> 0006 : 02FE PUSH PARAM -2
> 0007 : 02FF PUSH PARAM -1
> 0008 : AFFF ADD QUICK -1
> 0009 : 1C02 CALL (2)
> 0010 : 1A01 DROP (1)
> 0011 : 1002 RETURN (2)
>
> As for the runtime overhead, GOSUB at [1] is literally saving some context,
> including the instruction pointer, followed by a GOTO. The CALL instruction
> at [2] is obviously more complicated.
>
> Whereas the GoSub target offset is encoded in the instruction, pretty much
> every form of CALL requires some kind of lookup in the current context and
> parameter checks.
>
> Finally, running these two, hopefully comparable enough [*], implementations
> of the identity function:
>
> Public Function f(b As Integer) As Integer
> Dim a As Integer
> _Inc:
> Inc a
> Dec b
> If b Then GoSub _Inc
> Return a
> End
>
> Public Function g(b As Integer) As Integer
> If Not b Then Return b
> Return 1 + g(b - 1)
> End
>
> each with argument 10e4 and 10e4 times, I get the following timings in
> milliseconds:
>
> 3115
> 4246
>
> Regards,
> Tobi
>
> [1] https://gitlab.com/gambas/gambas/blob/master/main/gbx/gbx_exec_loop.c#L940
> [2] https://gitlab.com/gambas/gambas/blob/master/main/gbx/gbx_exec_loop.c#L1059
>
> [*] For example, I took care not to have g allocate a new local variable
> on each call, because f doesn't do that. Both do two additions per
> "iteration" and have a single conditional.
>
> --
> "There's an old saying: Don't change anything... ever!" -- Mr. Monk
>
> ----[ Gambas mailing-list is hosted by https://www.hostsharing.net ]----
>
> ----[ Gambas mailing-list is hosted by https://www.hostsharing.net ]----
------- End of Original Message -------
More information about the User
mailing list