Commit 7603afa2 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook GitHub Bot

avoid Function instantiating std::move over lambdas

Summary:
There are many lambda types so that can be a lot of instantiations. This shows up with futures, which use `Function` under the hood with lambdas.

It is not as helpful to avoid `std::move` completely - it is primarily important to avoid it over callables, since these locations are widely-instantiated but may also be the only instantiations over the callables.

```name=trunk
$ foundation/scripts/run-perf-compile --syntax folly/futures/test/FutureTest.cpp
     6,359,421,839      instructions:uP
```
```name=branch
$ foundation/scripts/run-perf-compile --syntax folly/futures/test/FutureTest.cpp
     6,331,468,279      instructions:uP
```

Reviewed By: Gownta, luciang

Differential Revision: D32971147

fbshipit-source-id: b2ce1325330ed59d9fb23fed48476fddf24e7854
parent 5e963ae5
...@@ -619,8 +619,8 @@ struct DispatchSmall { ...@@ -619,8 +619,8 @@ struct DispatchSmall {
static std::size_t exec(Op o, Data* src, Data* dst) noexcept { static std::size_t exec(Op o, Data* src, Data* dst) noexcept {
switch (o) { switch (o) {
case Op::MOVE: case Op::MOVE:
::new (static_cast<void*>(&dst->tiny)) ::new (static_cast<void*>(&dst->tiny)) Fun(static_cast<Fun&&>(
Fun(std::move(*static_cast<Fun*>(static_cast<void*>(&src->tiny)))); *static_cast<Fun*>(static_cast<void*>(&src->tiny))));
FOLLY_FALLTHROUGH; FOLLY_FALLTHROUGH;
case Op::NUKE: case Op::NUKE:
static_cast<Fun*>(static_cast<void*>(&src->tiny))->~Fun(); static_cast<Fun*>(static_cast<void*>(&src->tiny))->~Fun();
...@@ -868,10 +868,10 @@ class Function final : private detail::function::FunctionTraits<FunctionType> { ...@@ -868,10 +868,10 @@ class Function final : private detail::function::FunctionTraits<FunctionType> {
// Q: Why is is safe to destroy and reconstruct this object in place? // Q: Why is is safe to destroy and reconstruct this object in place?
// A: See the explanation in the move assignment operator. // A: See the explanation in the move assignment operator.
this->~Function(); this->~Function();
::new (this) Function(std::move(fun)); ::new (this) Function(static_cast<Fun&&>(fun));
} else { } else {
// Construct a temporary and (nothrow) swap. // Construct a temporary and (nothrow) swap.
Function(std::move(fun)).swap(*this); Function(static_cast<Fun&&>(fun)).swap(*this);
} }
return *this; return *this;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment