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
[SR-9905] passing array as array of existential super type is slow (allocates) #52311
Comments
The protocol witness tables aren't compatible; they chain by reference rather than putting one inside the other. |
@belkadan ah thanks! In other words, we need the allocation+copy in this case as what will need to happen is really (in pseudo-code) foo(arrayOfSubPWTs.map { $0.superPWT }) Or do you see any way of not doing that? In theory, it'd be possible to see that this is a unique reference to the array and replace the PWTs in-place rather than alloc+copy but I don't know enough to judge if that's possible or not. |
We don't really consider related protocols to have related representations today, but I suppose they could. They're all "existential box + witness table reference". That said, you're calling this thing in a loop, which means it has to keep the original array around anyway to do the conversion again. You'd only get the optimization in the "last use" case. |
yes, @belkadan, you're right. I put it in a loop so I can dtrace it easier 🙂. But I guess this program might be a better test case? import Darwin
protocol Super {}
protocol Sub: Super {}
struct Foo: Sub {}
@inline(never)
func foo(_ supers: [Super]) {
}
@inline(never)
func CHECK_ALLOCATIONS_HERE(_ things: [Sub]) {
foo(things)
}
CHECK_ALLOCATIONS_HERE([Foo(), Foo(), Foo(), Foo()]) // prime it
close(0xcafe) // just a dummy for the dtrace script
CHECK_ALLOCATIONS_HERE([Foo(), Foo(), Foo(), Foo(), Foo()])
close(0xdead) // just a dummy for the dtrace script which results in
so as expected, it doesn't apply that optimisation and allocates. |
@swift-ci create |
Drive by comment that the way to fix this is to remove this implicit conversion completely. |
Additional Detail from JIRA
md5: 5a14898a75863f85c86fa2ef5c938d2a
Issue Description:
I would expect this Swift program
to not allocate in the loop because
Sub
is a sub-type ofSuper
so I would think that[Sub]
should be directly compatible with[Super]
.I didn't think about this too much but I'd expect the PWTs of
Super
andSub
to be compatible (when used asSuper
) and therefore I'd think that passing a[Sub]
as[Super]
should be a no-op. I totally might be wrong here though.These are the allocations we see
The text was updated successfully, but these errors were encountered: