New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Performance regression for the .. operator in v5.21.5 #14334
Comments
From @avarCreated by @avarsri reported an issue with the .. operator being massively slower in Before that commit (one v5.21.4-50-g39ff6c3, commit earlier), on a And now: $ time ./miniperl -e 'my $str = "sub { my \$foo;"; $str .= "for (1..3){ \$foo .= \"test\"; }" x 3000; $str .= "}"; eval $str for 1 .. 100' Interestingly it seems from looking at that patch that some bugfix for $ time ./miniperl -e 'my $str = "sub { my \$foo;"; $str .= "for (\$_ = 1; \$_ <= 3; \$_++){ \$foo .= \"test\"; }" x 3000; $str .= "}"; eval $str for 1 .. 100' And after: $ time ./miniperl -e 'my $str = "sub { my \$foo;"; $str .= "for (\$_ = 1; \$_ <= 3; \$_++){ \$foo .= \"test\"; }" x 3000; $str .= "}"; eval $str for 1 .. 100' The increase in time between those two runs is probably means nothing In addition to the slowdown with the .. range operator, the Same commits & perl configuration, before: $ time ./miniperl -e 'my $str = "sub { my \$foo;"; $str .= "for (\$_ = 1; \$_ <= 3; \$_++){ \$foo .= scalar(0..0); }" x 3000; $str .= "}"; eval $str for 1 .. 100' After: Perl Info
|
From @cpansproutOn Sun Dec 14 10:54:28 2014, avar wrote:
It’s the same operator internally; it just behaves differently depending on the context. In the context of foreach(...), a range operator is created at first, and then it gets taken apart when it turns out to be the only thing in foreach’s list. I notice your test case is solely testing the timing of compilation. At run-time I would not expect to see any difference, unless you write foreach(scalar($foo..$bar)) or \scalar($foo..$bar). The only real compile-time difference is the use of pad_add_name_pvn instead of pad_alloc, so it may be worth looking into why lexical variable creation is much slower than target allocation.
Again, you are not even running code, just compiling it. Furthermore, you don’t use .. in any lvalue context, so no copying would happen.
-- Father Chrysostomos |
The RT System itself - Status changed from 'new' to 'open' |
From @avarThanks for the clarification. When sri noted this on #p5p he mentioned On Mon, Dec 15, 2014 at 1:20 AM, Father Chrysostomos via RT
|
From @cpansproutOn Sun Dec 14 16:20:57 2014, sprout wrote:
The reason for the slowdown is that, by putting thousands of ..’s in the same sub, you are creating a HUGE pad that takes a long time to search, since pad lookup is linear. (I want to replace pad lookup with a binary search if possible, but it would be very tricky to get right, because things are not always in order.) The thing that usually saves the day for pathological cases is an optimisation I added in 5.20 (v5.19.2-231-g7db6405) that records the maximum named slot. I did that because constants added to the pad under threaded builds get relocated to the pad at the end of the sub’s compilation, so the pad may double in size, causing pad lookup for string eval in that sub to be twice as slow. However, 5.18.3 appears just as fast as 5.20, so my initial guess as to the cause may be completely wrong.... -- Father Chrysostomos |
From @cpansproutOn Sun Dec 14 16:48:29 2014, avar wrote:
Aha, generated code! The bane of pad lookup algorithms. :-) See the commit message of v5.19.2-231-g7db6405. -- Father Chrysostomos |
From @cpansproutOn Sun Dec 14 16:50:17 2014, sprout wrote:
Fixed in dd5d1b8. The reason for the slowdown was that the name pad was getting extended by flipflop/range targets, whereas previously it was not. It’s the name pad that gets searched when symbols are looked up. In 5.20 and earlier (and current bleadperl as of dd5d1b8), you can see the same slowdown if you add a ‘my $x’ to your generated code, because then the name pad gets extended (numbers from 5.18.4): $ time ./miniperl -e 'my $str = "sub { my \$foo;"; $str .= "for (1..3){ \$foo .= \"test\"; }" x 3000; $str .= "}"; eval $str for 1 .. 100' real 0m2.280s real 1m0.014s which is really not ideal. I’m just trying to avoid making things slower than before. -- Father Chrysostomos |
@cpansprout - Status changed from 'open' to 'resolved' |
Migrated from rt.perl.org#123430 (status was 'resolved')
Searchable as RT123430$
The text was updated successfully, but these errors were encountered: