I think the reason for this slowdown is that when constructing support for the lvalue property of substr,
No, it's only done when necessary, and it's not here.
>perl -MO=Concise -e"\substr($_,1)" 2>&1 | find "substr" 5 <@> substr[t4] sKRM/2 ->6 ^ | "M"odifiable => magic created. >perl -MO=Concise -e"$a = substr($_,1)" 2>&1 | find "substr" 5 <@> substr[t3] sK/2 ->6 ^ | Not modifiable => no magic created.
The time is spent creating new strings and assigning them.
Pass 1: Creates a 79,999 char string & copies it into $a's buffer Pass 2: Creates a 79,998 char string & copies it into $a's buffer Pass 3: Creates a 79,997 char string & copies it into $a's buffer ... Pass 79,999: Creates a 1 char string & copies it into $a's buffer Pass 80,000: Creates a 0 char string & copies it into $a's buffer
It's copying (((N-1)+1)(N-1)/2)*2 = (N^2 - N) = 6,399,920,000 bytes!
However, it's possible to do what you want without copying a singly byte! Through a feature called "OOK", Perl can efficiently remove the leading chars of strings when it does so in-place.
$a =~ s/.//s; # Remove leading char with no copying. substr($a, 0, 1, ''); # Remove leading char with no copying.
The latter even returns the character removed! (Well, so does the former if you add a capture.)
Benchmarks:
-------------------- 20,000 Rate substr3 s/// substr4 substr3 1.61/s -- -93% -96% s/// 23.1/s 1336% -- -44% substr4 41.2/s 2460% 78% -- -------------------- 40,000 Rate substr3 s/// substr4 substr3 0.884/s -- -96% -98% s/// 23.1/s 2509% -- -45% substr4 41.6/s 4606% 80% -- -------------------- 80,000 Rate substr3 s/// substr4 substr3 0.445/s -- -98% -99% (warning: unreliable count) s/// 23.4/s 5162% -- -42% substr4 40.1/s 8897% 71% --
The rate is the number of times 80,000 chars can be processed per second. Notice how the 4-arg substr and s/// aren't affected by the length of the input?
In reply to Re: Using substr to split a string scales as N^2 -- alternatives?
by ikegami
in thread Using substr to split a string scales as N^2 -- alternatives?
by hrr
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |