Paul writes:
> 
> --- Brian Ingerson <[EMAIL PROTECTED]> wrote:
> > Garrett Goebel wrote:
> > > 
> > > From: Paul [mailto:[EMAIL PROTECTED]]
> > > >
> > > > Anybody know offhand *why* my() lexicals are supposedly faster?
> 
> ....
> 
> > Yes this is OT, but I'll contribute to the problem as well...
> > 
> > My coworker Gisle Aas (maybe you've heard of him ;) says that globals
> > and lexicals have identical speed because Perl optimizes out the
> > symbol-table lookup.
> > 
> > Trust Gisle.
> 
> lol -- now *there's* an answer.
> So for my details I should go to the parse tree docs, and the code, I'm
> thinking.
> 
> BTW -- with many thanks to everyone -- my question was "why are they
> faster", but the reason was never the speed -- it was to understand the
> way Perl stores and *accesses* lexicals.
> 
> Any input? =o)

If you have a reasonably recent Perl, you can do the following:

    % perl -MO=Terse,exec -e '$f = 123'
    OP (0x8180688) enter
    COP (0x8180628) nextstate
    SVOP (0x8175298) const  IV (0x80f8770) 123
    SVOP (0x817b488) gvsv  GV (0x81017b0) *f
    BINOP (0x8180600) sassign
    LISTOP (0x8180660) leave

    % perl -MO=Terse,exec -e 'my $f = 123'
    OP (0x81805d0) enter
    COP (0x8180598) nextstate
    SVOP (0x8104b88) const  IV (0x8104c9c) 123
    OP (0x817b490) padsv [1]
    BINOP (0x81761f0) sassign
    LISTOP (0x81752a0) leave

As you can see from the output, for a non-lexical $f, Perl uses an
opcode "gvsv GV *f". The gvsv instruction gets a pointer to the
entire glob (*f) from which it dereferences the SV (scalar) part and
pushes it on the stack. See pp_hot.c:

    PP(pp_gvsv)
    {
        djSP;
        EXTEND(SP,1);
        if (PL_op->op_private & OPpLVAL_INTRO)
            PUSHs(save_scalar(cGVOP_gv));
        else
            PUSHs(GvSV(cGVOP_gv));
        RETURN;
    }

For the lexical, Perl has already determined at compile time that
$f is in pad slot number 1 (think stack or register allocation).
padsv is:

    PP(pp_padsv)
    {
        djSP; dTARGET;
        XPUSHs(TARG);
        ...

If you navigate all the macros, you'll find that takes curpad
(a pointer to an array of SV pointers: the current "stack frame"
where "stack" is in the sense of a traditional compiler, not the
(main) Perl stack) and pushes curpad[1] (remember $f was allocated
slot 1 at compile time) onto the (main Perl) stack.

--Malcolm

-- 
Malcolm Beattie <[EMAIL PROTECTED]>
Unix Systems Programmer
Oxford University Computing Services

Reply via email to