[Gambas-user] Are GoSubs efficient?
Cedron Dawg
cedron at exede.net
Mon Apr 22 22:41:46 CEST 2019
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 ]----
More information about the User
mailing list