The time needed to perform $x =~ s/.//; and substr($x,0,1) = ''; is not related to the length of $x thanks to the "OOK" optimization.
Instead of
- allocating a new buffer,
- copying the the string to the new buffer minus the leading char,
- assigning the new buffer to the variable and
- freeing the old buffer
those two operations
- increment the pointer to the buffer in the variable,
- assign 1 to the IV slot* of the variable if the OOK flag is off or
- increment the IV slot* of the variable if the OOK flag is on, and
- turn on the OOK flag
The string is never copied. You can see this in effect in the following snippet:
>perl -MDevel::Peek -e"my $x='abcdef'; Dump($x); substr($x,0,1)=''; Du
+mp($x);"
SV = PV(0x226104) at 0x2252e8
REFCNT = 1
FLAGS = (PADBUSY,PADMY,POK,pPOK)
PV = 0x182ca64 "abcdef"\0
CUR = 6
LEN = 8
SV = PVIV(0x227134) at 0x2252e8
REFCNT = 2
FLAGS = (PADBUSY,PADMY,POK,OOK,pPOK)
IV = 1 (OFFSET)
PV = 0x182ca65 ( "a" . ) "bcdef"\0
CUR = 5
LEN = 7
If POK is true and OOK is false, then
string start = PV
string length = CUR
number bytes allocated = LEN
start of buffer = PV
If POK is true and OOK is true, then
string start = PV
string length = CUR
number bytes allocated = LEN + IV
start of buffer = PV - IV
* — Nicholas Clark recently made a change to Perl so that the chopped bytes are used instead of the IV slot. That hasn't appeared in any Perl release yet.
Update: Changed substr($x,0,1,''); to substr($x,0,1)=''; since the rest of the thread used the latter.
|