-
Notifications
You must be signed in to change notification settings - Fork 10.5k
SILOptimizer: Replace [].append(contentsOf:) with [].append(element:) #6652
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
Conversation
If you pull the benchmark you've added out into a separate PR and merge that first, you'll be able to see the impact via asking at-swift-ci please benchmark in this PR. Note, this PR landed recently and touches |
@airspeedswift thanks for the tip. This was already rebased on top of your PR, and tests were fine. I'll pull the benchmark out to a separate PR now. |
1b59b2f
to
02ce5ac
Compare
I realized in #6653 that I've been holding the benchmark driver wrong. It looks like this pull request does cause a regression in ArrayAppend.
|
On second thought, that benchmark run appears to be running without optimizations, so the results are expected. The regression in ArrayAppend is expected, because my semantics tag is stopping a method from being inlined. The performance improvement in the my new test (26x) is also much more significant than it was in my earlier testing (~6x), because I was testing with optimizations enabled. I'm not sure how to run the benchmarks with optimizations locally. The build script flags for setting iteration counts don't seem to be working. |
It occurs to me that maybe, when we detect this, we should be issuing a compiler warning that lets the user know there's a more appropriate way to do this, rather than optimizing away the problems from the incorrect usage. Or maybe both, but that's probably pointless. |
There is nothing wrong with writing |
"There is nothing wrong with writing |
Then again, I think the reason why we don't have overloads to do |
This optimization doesn't only target single element appends. It also unrolls If I recall, |
Ah OK I see, the 2+ case is fair game. Then again, by unrolling the Sorry for the rehash if you've already accounted for this... |
I did not account for that scenario. I haven't looked at Array's implementation, but if it doubles the size of its buffer each time, then that scenario gets exceedingly rare quite quickly. The wasted time should be dwarfed by the performance gains. A benchmark for this also wouldn't reflect real-world use of |
Yup it doubles each time. It would be rare for large arrays, but could easily happen for small ones. You're right, it may not be very material though. |
@swift-ci Please test |
Build failed |
Build failed |
@slavapestov we should also test with |
preset=buildbot,tools=RA,stdlib=RD |
preset=buildbot,tools=RA,stdlib=RD |
Build failed |
@ben-ng I think I kicked it off correctly. This one takes several hours, so I'll merge this patch tonight if it succeeds. Thank you for your contribution! |
@slavapestov I'd still ideally like to see the benchmarks run from the PR before merging, but that's dependent on #6653 getting merged. |
@airspeedswift I agree, I'll make the changes to the benchmark PR now so that it can be run & merged. |
Great, thanks!
…On Wed, Jan 11, 2017 at 7:08 PM Ben Ng ***@***.***> wrote:
@airspeedswift <https://github.com/airspeedswift> I agree, I'll make the
changes to the benchmark PR now so that it can be run & merged.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#6652 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AHr1pREqC2cyRGLhhEZYtHwldl5RFPL5ks5rRZk3gaJpZM4Ldmyn>
.
|
Can I get a @swift-ci please benchmark on this now that the benchmarks are merged? |
Does this have the added 2nd benchmark? That might be the conflict the merge button is flagging... can you rebase that in? |
02ce5ac
to
75b6dba
Compare
Oh right, I forgot to rebase. Done. |
@swift-ci please benchmark |
@swift-ci please test |
Build failed |
Build failed |
@swift-ci Please benchmark |
Build comment file:Optimized (O) Regression (7)
Improvement (4)
No Changes (146)
Regression (1)
Improvement (4)
No Changes (152)
|
Build comment file:Optimized (O) Regression (9)
Improvement (7)
No Changes (141)
Regression (3)
Improvement (2)
No Changes (152)
|
Good thing we ran that benchmark on this, those are surprising results. Not only were there quite a few regressions, it looks like the "magic number" where this optimization should bail out is actually around 23. |
@ben-ng Are you referring to the max number of elements? We should also take care about code size. Even if the performance is okay, we should have a reasonable low limit to prevent code size explosion. |
@eeckstein @ben-ng Another question to consider is can this number change over time? If the number changes over time, do we have any tests that vary the number so that we can verify this? I imagine the way to do it would be to have a gybed extension, no? |
75b6dba
to
e69ff06
Compare
Can I please get another benchmark run on this? |
@swift-ci Please benchmark |
I'll give you 2 ; ) |
@swift-ci Please benchmark |
Hmmm... I thought we could run multiple benchmarking jobs at the same time. Guess not. Sorry for restarting the timer on the benchmarking job! |
Build comment file:Optimized (O) Regression (6)
Improvement (1)
No Changes (167)
Regression (2)
Improvement (0)No Changes (172)
|
Oops, it looks like I moved the pass too early. I'll have to look into why the test didn't catch that... |
@ben-ng I'd like to get your change in. If you don't mind I'll create another pull request containing your patch plus some fixes. |
Hey @eeckstein, I don't mind at all. I haven't been able to figure out how to get this optimization to work without blocking other optimization passes. The problem is that it adds a semantic attribute to functions that themselves contain calls to functions with semantic attributes, and that stops some calls from being inlined where they were before. I tried moving the pass earlier, but that caused one of the specialization tests to fail. I haven't had time to continue debugging the problem since then. |
@ben-ng Great, thanks! I think your approach is basically fine. It just needs some minor tweaks. |
Merged in #8464 |
This makes
myArray += [42]
equivalent tomyArray.append(42)
, which results in a 6x speedup. It does this by modifying the ArrayElementValuePropagation pass, replacing calls toArray.append(contentsOf:
with calls toArray.append(element:
.Re-submission of #5978, which was reverted in #6103 because it caused a memory leak in the
stdlib/Dictionary.swift
andstdlib/Set.swift
tests. The problem was that I never destroyed the copy of the value. That has been fixed.@gottesmm mentioned that there was also a benchmarking regression in ArrayAppend. Is it because I added a new benchmark in this pull request, and the driver only reports the aggregate time for the entire file? I don't see how this optimization could affect the results of the existing tests.