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?

Benchmark code


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

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.