I just started to do some rpc releating things.
When creating a async call, I have to call a NewCallback
For example
// See Closure.
template <typename Class, typename Arg1, typename Arg2>
inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1, Arg2),
Arg1 arg1, Arg2 arg2) {
return new internal::MethodClosure2<Class, Arg1, Arg2>(
object, method, true, arg1, arg2);
}
Inside the NewCallback call, it create a MethodClosure object, its' ctor and run methods is:
MethodClosure2(Class* object, MethodType method, bool self_deleting,
Arg1 arg1, Arg2 arg2)
: object_(object), method_(method), self_deleting_(self_deleting),
arg1_(arg1), arg2_(arg2) {}
void Run() override {
bool needs_delete = self_deleting_; // read in case callback deletes
(object_->*method_)(arg1_, arg2_);
if (needs_delete) delete this;
}
So, as I understand, the arg1 and arg2 is copied 3 times when creating the NewCallback object with below code. And extra 1 time in (object_->*method_)(arg1_, arg2_);.
int a;
std::shared_ptr<string> s;
NewCallback(this, func1, a, s);
Even if i use move semantic, there are still 3 times copy and 1 time move for a full async call. (Twice for creating NewCallback, and rest for real call of the callback function.)
int a
std::shared_ptr<string> s;
NewCallback(this, func1, a, std::move(s));
The primitive type and pointer are ok, but shared pointer is really expensive, I made a little experiment in my laptop, it takes 1s per 10k times copy.
So my question are,
- Is my understanding about times of 'times of object copy' correct?
- Shall I concern on this? Or should I only use primitive type or raw pointer in the callback to avoid the expensive copy?
- If this is right to concern, maybe I can optimize the call with std::move or std::forward to reduce copy times.