[Gambas-user] Are GoSubs efficient?

Tobias Boege taboege at gmail.com
Mon Apr 22 21:18:47 CEST 2019

On Mon, 22 Apr 2019, Cedron Dawg wrote:
> I'm a big fan of GoSubs.  See my last post in
> https://forum.gambas.one/viewtopic.php?f=4&t=694
> The question I have about GoSubs in Gambas is how lightweight are they compared to a regular sub call?

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
    Dec a
    GoSub _Next
    f(a, b - 1)

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 a
    Dec b
    If b Then GoSub _Inc
    Return a

  Public Function g(b As Integer) As Integer
    If Not b Then Return b
    Return 1 + g(b - 1)

each with argument 10e4 and 10e4 times, I get the following timings in



[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

More information about the User mailing list