This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Make eval "s//<<END/e" slightly faster
authorFather Chrysostomos <sprout@cpan.org>
Wed, 29 Aug 2012 20:10:01 +0000 (13:10 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Fri, 31 Aug 2012 01:18:08 +0000 (18:18 -0700)
The code that peeks into an outer linestr buffer to find the heredoc
body has to modify that buffer and remove the heredoc body from it.

It copies the text after the quote-like operator up to the end of the
line into a new SV, concatenates the text after the heredoc body into
a new SV, and then copies it back to linestr right after the quote-
like operator.

So, in this example:

eval "s//<<END/e; # jiggles\nfoo\nEND\ndie;"

It ends up copying this:

               "; # jiggles\ndie;\n;"

into this at the position shown:

eval "s//<<END/e; # jiggles\nfoo\nEND\ndie;\n;"
                ^

There is no need for two copies.  And there is no need to copy the
rest of the line where the heredoc marker is.

toke.c

diff --git a/toke.c b/toke.c
index 5f568b1..7d7fb88 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -9678,7 +9678,6 @@ S_scan_heredoc(pTHX_ register char *s)
            CopLINE_set(PL_curcop, (line_t)PL_multi_start-1);
            missingterm(PL_tokenbuf + 1);
        }
            CopLINE_set(PL_curcop, (line_t)PL_multi_start-1);
            missingterm(PL_tokenbuf + 1);
        }
-       sv_setpvn(herewas,bufptr,d-bufptr+1);
        sv_setpvn(tmpstr,d+1,s-d);
        s += len - 1;
        shared->herelines++;    /* the preceding stmt passes a newline */
        sv_setpvn(tmpstr,d+1,s-d);
        s += len - 1;
        shared->herelines++;    /* the preceding stmt passes a newline */
@@ -9697,12 +9696,9 @@ S_scan_heredoc(pTHX_ register char *s)
            cx->blk_eval.cur_text = newSVsv(linestr);
            SvSCREAM_on(cx->blk_eval.cur_text);
        }
            cx->blk_eval.cur_text = newSVsv(linestr);
            SvSCREAM_on(cx->blk_eval.cur_text);
        }
-       s++;
-       sv_catpvn(herewas,s,bufend-s);
-       Copy(SvPVX_const(herewas),bufptr,SvCUR(herewas) + 1,char);
+       Move(s,d,bufend-s + 1,char);
        SvCUR_set(linestr,
        SvCUR_set(linestr,
-                 bufptr-SvPVX_const(linestr)
-                  + SvCUR(herewas));
+                 SvCUR(linestr) - (s-d));
 
        s = olds;
        goto retval;
 
        s = olds;
        goto retval;