diff options
author | Father Chrysostomos <sprout@cpan.org> | 2011-11-25 23:04:22 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2011-11-26 14:33:47 -0800 |
commit | 24fcb59fcc2fac06ec8b42aeedb3a16987d87db4 (patch) | |
tree | c975ed9172a79e92712e3dcba8a279bb6972bbe1 /t | |
parent | a74fb2cdc8f2121774cc6d2b5e9ddd01a96db467 (diff) | |
download | perl-24fcb59fcc2fac06ec8b42aeedb3a16987d87db4.tar.gz |
Optimise substr assignment in void context
In void context we can optimise
substr($foo, $bar, $baz) = $replacement;
to something like
substr($foo, $bar, $baz, $replacement);
except that the execution order must be preserved. So what we actu-
ally do is
substr($replacement, $foo, $bar, $baz);
with a flag to indicate that the replacement comes first. This means
we can also optimise assignment to two-argument substr the same way.
Although optimisations are not supposed to change behaviour,
this one does.
• It stops substr assignment from calling get-magic twice, which means
the optimisation makes things less buggy than usual.
• It causes the uninitialized warning (for an undefined first argu-
ment) to mention the substr operator, as it did before the previous
commit, rather than the assignment operator. I think that sort of
detail is minor enough.
I had to make the warning about clobbering references apply whenever
substr does a replacement, and not only when used as an lvalue. So
four-argument substr now emits that warning. I would consider that a
bug fix, too.
Also, if the numeric arguments to four-argument substr and the
replacement string are undefined, the order of the uninitialized warn-
ings is slightly different, but is consistent regardless of whether
the optimisation is in effect.
I believe this will make 95% of substr assignments run faster. So
there is less incentive to use what I consider the less readable form
(the four-argument form, which is not self-documenting).
Since I like naïve benchmarks, here are Before and After:
$ time ./miniperl -le 'do{$x="hello"; substr ($x,0,0) = 34;0}for 1..1000000'
real 0m2.391s
user 0m2.381s
sys 0m0.005s
$ time ./miniperl -le 'do{$x="hello"; substr ($x,0,0) = 34;0}for 1..1000000'
real 0m0.936s
user 0m0.927s
sys 0m0.005s
Diffstat (limited to 't')
-rw-r--r-- | t/lib/warnings/9uninit | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/t/lib/warnings/9uninit b/t/lib/warnings/9uninit index b76c2ef370..0d2d84141b 100644 --- a/t/lib/warnings/9uninit +++ b/t/lib/warnings/9uninit @@ -1019,17 +1019,17 @@ Use of uninitialized value $m1 in substr at - line 5. Use of uninitialized value $m2 in substr at - line 6. Use of uninitialized value $g1 in substr at - line 6. Use of uninitialized value $m1 in substr at - line 6. -Use of uninitialized value $g2 in substr at - line 7. Use of uninitialized value $m2 in substr at - line 7. Use of uninitialized value $g1 in substr at - line 7. +Use of uninitialized value $g2 in substr at - line 7. Use of uninitialized value $m1 in substr at - line 7. Use of uninitialized value $g1 in substr at - line 8. -Use of uninitialized value in scalar assignment at - line 8. -Use of uninitialized value $m1 in scalar assignment at - line 8. +Use of uninitialized value $g2 in substr at - line 8. +Use of uninitialized value $m1 in substr at - line 8. Use of uninitialized value $m2 in substr at - line 9. Use of uninitialized value $g1 in substr at - line 9. -Use of uninitialized value in scalar assignment at - line 9. -Use of uninitialized value $m1 in scalar assignment at - line 9. +Use of uninitialized value $g2 in substr at - line 9. +Use of uninitialized value $m1 in substr at - line 9. Use of uninitialized value $m2 in vec at - line 11. Use of uninitialized value $g1 in vec at - line 11. Use of uninitialized value $m1 in vec at - line 11. |