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 /lib/Class | |
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 'lib/Class')
0 files changed, 0 insertions, 0 deletions