Re: Very[OT]:Technical query re: scratchpad lookups for my() vars
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
Re: Very[OT]:Technical query re: scratchpad lookups for my() vars
Paul wrote: --- Robert Landrum [EMAIL PROTECTED] wrote: I could be wrong, but as I recall, when your program enters a scope, perl immediatly identifies the the scratchpad to use. Then, it need only search backwards up the tree of scratchpads to find the variable "$x", which is faster than iterating through the STHASH looking for a localized or global $x. But how does it locate x in the scratchpad? Where're the docs? Or am I gonna have to read the code? =lol! Chapter 20 in "Advanced Perl programming"
Re: Very[OT]:Technical query re: scratchpad lookups for my() vars
Many thanks to everyone, Malcolm in particular, for humoring my curiosity and assisting my esoteric research. Hope it helped someone else, too, and sorry for cluttering up the board. But it *dod* say it was Very[OT]. ;o) Paul --- Malcolm Beattie [EMAIL PROTECTED] wrote: 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 __ Do You Yahoo!? Yahoo! Auctions - Buy the things you want at great prices. http://auctions.yahoo.com/
RE: Very[OT]:Technical query re: scratchpad lookups for my() vars
Title: RE: Very[OT]:Technical query re: scratchpad lookups for my() vars From: Paul [mailto:[EMAIL PROTECTED]] Anybody know offhand *why* my() lexicals are supposedly faster? Because a dynamic variable allocates a new value at runtime which occludes the global value until it's scope expires. In contrast, a lexical variable is unique to its code value's (CV) context which was determined at parse time. However, if you recursively call that CV, then Perl has to allocate a new value for the lexical. Urban legend says that lexicals are on average 10% faster than dynamic variables. I wonder if that is true... and what difference recursion makes. I wonder how you'd write a script to benchmark that and actually benchmark the right thing...
Re: Very[OT]:Technical query re: scratchpad lookups for my() vars
Garrett Goebel wrote: From: Paul [mailto:[EMAIL PROTECTED]] Anybody know offhand *why* my() lexicals are supposedly faster? Because a dynamic variable allocates a "new" value at runtime which occludes the global value until it's scope expires. In contrast, a lexical variable is unique to its code value's (CV) context which was determined at parse time. However, if you recursively call that CV, then Perl has to allocate a new value for the lexical. Urban legend says that lexicals are on average 10% faster than dynamic variables. I wonder if that is true... and what difference recursion makes. I wonder how you'd write a script to benchmark that and actually benchmark the right thing... 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. -- perl -le 'use Inline C=q{SV*JAxH(char*x){return newSVpvf ("Just Another %s Hacker",x);}};print JAxH+Perl'
Very[OT]:Technical query re: scratchpad lookups for my() vars
Anybody know offhand *why* my() lexicals are supposedly faster? If they're stored on a scratchpad for the scope, which is an array, (technically a stack of them to accommodate recursion,) then exactly how does Perl go about finding which data location you mean when you say $x for a lexical? $::x has to go through the package lookup, which (if I recall correctly) is technically a hash element of a hash element at least..but if the scratchpad has a lot of scope-specific lexicals, how does it find which one is x? my $brain = 'tapioca'; #=o) __ Do You Yahoo!? Yahoo! Auctions - Buy the things you want at great prices. http://auctions.yahoo.com/
Re: Very[OT]:Technical query re: scratchpad lookups for my() vars
--- Robert Landrum [EMAIL PROTECTED] wrote: I could be wrong, but as I recall, when your program enters a scope, perl immediatly identifies the the scratchpad to use. Then, it need only search backwards up the tree of scratchpads to find the variable "$x", which is faster than iterating through the STHASH looking for a localized or global $x. But how does it locate x in the scratchpad? Where're the docs? Or am I gonna have to read the code? =lol! I think Mark-Jason Dominus has much more indepth look at the perl internals on his website... plover.com Great articles, read them today. Learned a new trick: my $fh = do { local *FH; }; But nothing about the structural/algorithmic mechanics. : __ Do You Yahoo!? Yahoo! Auctions - Buy the things you want at great prices. http://auctions.yahoo.com/
Re: Very[OT]:Technical query re: scratchpad lookups for my() vars
At 03:52 PM 3/14/01 -0800, Paul wrote: But nothing about the structural/algorithmic mechanics. : From the perlsub docs: Variables declared with my are not part of any package and are therefore never fully qualified with the package name. In particular, you're not allowed to try to make a package variable (or other global) lexical: my $pack::var; # ERROR! Illegal syntax my $_; # also illegal (currently) In fact, a dynamic variable (also known as package or global variables) are still accessible using the fully qualified :: notation even while a lexical of the same name is also visible: package main; local $x = 10; my$x = 20; print "$x and $::x\n"; That will print out 20 and 10. There is _no_ stash of lexicals during execution, only during compilation. I guess one of the reasons lexicals are faster. Elizabeth Mattijsen
Re: Very[OT]:Technical query re: scratchpad lookups for my() vars
--- Elizabeth Mattijsen [EMAIL PROTECTED] wrote: At 03:52 PM 3/14/01 -0800, Paul wrote: But nothing about the structural/algorithmic mechanics. : From the perlsub docs: Variables declared with my are not part of any package and are therefore never fully qualified with the package name. In particular, you're not allowed to try to make a package variable (or other global) lexical: my $pack::var; # ERROR! Illegal syntax my $_; # also illegal (currently) In fact, a dynamic variable (also known as package or global variables) are still accessible using the fully qualified :: notation even while a lexical of the same name is also visible: package main; local $x = 10; my$x = 20; print "$x and $::x\n"; That will print out 20 and 10. There is _no_ stash of lexicals during execution, only during compilation. I guess one of the reasons lexicals are faster. Elizabeth Mattijsen An excellent example, all known and understood. What I can't find is this: I know that my($x) puts x on this scope's scratchpad (and not in any package space), but rather than a hash named main:: with a key named x (which is, as I understand it, an oversimplification perhaps, but basically what Perl does internally for $main::x), exactly *how* does Perl "put" x into the scratchpad AV*? and once it's there, what did it store? How does it know that entry is 'x'? is it just a reference to the actual value? None of this is critical for anything I'm doing right now, but I'm a detail hound. I want to *understand* it, so that in the future I can make intelligent decisions about what would be a "better" way to write any given algorithm, without just relying on popular wisdom and "urban legend". =o) (That's why I said it was Very[OT], lol) Paul __ Do You Yahoo!? Yahoo! Auctions - Buy the things you want at great prices. http://auctions.yahoo.com/