in reply to Re: named sub, subref and magic goto speed
in thread named sub, subref and magic goto speed

Oops! Good catch. I wonder how perl's not bailing out complaining e.g.

Can't find label CODE(0x81678a0) at sub.pl line 13.

and seems to be doing the right thing instead. The corrected code yields

Rate refcall named goto refcall 708190/s -- -1% -10% named 717414/s 1% -- -9% goto 790676/s 12% 10% --
but your previous reply (Re: named sub, subref and magic goto speed) explains that well: the goto &$ref essentially saves the building of one stack frame; that makes sense, thank you.

<update>

Uhm, no, goto &sub does create a new stack frame. From what I read in pp_ctl.c without knowing all those macros, I guess it's working like this:

A new frame is created, the old frame is unwound (sort of return), the old frame inspected (whether inside a sub, an eval, a loop and so on), then @_ pushed onto the stack again and the new frame is entered (sort of call).

It seems that the magic goto &function works along the semantics of

my $ref = *function{'CODE'}; # get a reference goto $ref; # magic goto to that reference

which explains why the goto &$coderef is more expensive - it does an extra deref and ref step:

my $ref = \&{$coderef}; # get a reference (\&{&$ref} without +the call) goto $ref; # magic goto to that reference

whereas whithout the & we have just

goto $ref; # we have a code reference, just use +that

Roughly. I mean, explaining what's going on in C speaking perl is sort of... well ;-)

The relevant part of a diff of the output of two runs of the same code (foo.pl), once with goto $ref and once with goto &$ref (with -Dtls) shows what's going on:

--- g_ref.Dtls +++ g_amp.Dtls @@ -69,7 +69,13 @@ => (foo.pl:5) nextstate => +(foo.pl:5) pushmark + => * (foo.pl:5) padsv($ref) + => * \CV(__ANON__) +(foo.pl:5) rv2cv + => * CV(__ANON__) +(foo.pl:5) refgen => \CV(__ANON__) (foo.pl:5) goto (foo.pl:5) (Found sub #1)

<update>

--shmem

_($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                              /\_¯/(q    /
----------------------------  \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

Replies are listed 'Best First'.
Re^3: named sub, subref and magic goto speed
by ikegami (Patriarch) on Dec 14, 2006 at 09:01 UTC

    Oops! Good catch. I wonder how perl's not bailing out complaining

    Because it DWYM instead. The docs say a label is expected, but if a code ref is provided, goto $ref is treated as goto &$ref. Personally, I consider it a bug in the docs (not in Perl or your code) because there's no reason to treat goto $ref as it if were goto "$ref".

    $\ = "\n"; sub foo { print @_ } my $ref = \&foo; sub { @_=('$ref->(@_)'); $ref->(@_); }->(); sub { @_=('foo(@_)'); foo(@_); }->(); sub { @_=('goto $ref'); goto $ref; }->(); sub { @_=('goto &$ref'); goto &$ref; }->();
      Sure there is; goto $label, where $label is an object expected to return a label string, and the object happens to be based on a coderef.