In the following code, populateData
does an unnecessary copy of the vector:
struct A {
vector<int> data;
ACTOR static Future<Void> populateData(A* self, int size) {
vector<int> _data = wait(produce(size));
self->data = std::move(_data);
}
static Future<vector<int>> produce(int size) {
return vector<int>(size, 0);
}
};
Calling wait(function_producing_future(args))
is a common pattern in FDB code, so reducing the number of copies in this scenario could potentially lead to large performance improvements, as https://github.com/apple/foundationdb/pull/2915 did. There are also other scenarios where it is possible to move the result of a future, but the actor compiler generates code that creates unnecessary copies.
The current plan is to create a new class:
template<class T>
struct MovableSAV : public SAV<T> {
...
};
which overrides the finishSendAndDelPromiseRef
function to move the SAV contents instead of copy them. The actor compiler can then detect scenarios where itâs safe to use a MovableSAV
instead of SAV
. Other changes in the actor compiler can generate code that supports perfect forwarding.
This issue has already been discussed some with various people at Snowflake and Apple, but I created this forum post as a place for people to post other ideas to help reduce the number of unnecessary copies.