in reply to Re: Ways to delete start of string
in thread Ways to delete start of string

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

  1. allocating a new buffer,
  2. copying the the string to the new buffer minus the leading char,
  3. assigning the new buffer to the variable and
  4. freeing the old buffer

those two operations

  1. increment the pointer to the buffer in the variable,
  2. assign 1 to the IV slot* of the variable if the OOK flag is off or
  3. increment the IV slot* of the variable if the OOK flag is on, and
  4. 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.