perf: Mark all types that are used only in std::shared_ptr<T>
as SWIFT_NONCOPYABLE
#435
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This PR avoids copying a few C++ types when using them in Swift, effectively speeding up the codebase by a few factors depending on how heavy the types were to copy. 🔥
Problem
Swift imports all C++ types as value types, so every time you get, use, or pass a C++ type around in Swift, it will make a copy.
Not only is this slow, but sometimes it isn't even expected and might destroy internal state if the C++ class has unsafe pointers inside that are not ref-counted!⚠️ ❌
std::shared_ptr<T>
is one of these cases - if you useshared_ptr.pointee
, it will actually return the pointer this shared_ptr wraps by value - so it will copyT
!! ❌Solution
So this PR changes this - every type we use inside of a
std::shared_ptr
is now marked as aSWIFT_NONCOPYABLE
, meaning Swift will not copy this type. It is likeSWIFT_IMMORTAL_REFERENCE
, but a bit more explicit on the usage.Right now, the following types are affected and have been improved with this PR;
Promise<T>
ArrayBuffer
std::function
Future
Every type that is not expected to be copied directly should have
SWIFT_NONCOPYABLE
on it, so that's;shared_ptr<T>
,unique_ptr<T>
orweak_ptr<T>
)const &
typesThen Swift can use borrowing magic.
Also, I guess an even better solution would be to have a
borrowing T
accessor instead of justT
on the Swift shared_ptr type. I created a feature request for this here: swiftlang/swift#78296