What's the overhead of destructing std::future
?
When I was reading the pdf , it noticed that:
// Example 1
// (a)
{
async( []{ f(); } );
async( []{ g(); } );
}
// (b)
{
auto f1 = async( []{ f(); } );
auto f2 = async( []{ g(); } );
}
Users are often surprised to discover that (a) and (b) do not have the same behavior, because normally we ignore (and/or don’t look at) return values if we end up deciding we’re not interested in the value and doing so does not change the meaning of our program.
But I checked the difference in the quickbench, , It was the opposite of what I thought. Am I missing any point of the discussion?
I suspect std::this_thread::sleep_for(1000ms)
to be the culprit here. Putting a thread to sleep and waking it up again is not a very precise operation. Sometimes a thread is woken up a little earlier, sometimes too early, so it has to be put back to sleep. If you remove the sleep (or use a deterministic operation instead), you can see that they're basically identical.
async
IssueSkimming the PDF, the issue Herb is talking about, is if you chain multiple async calls, they might execute differently depending on whether you assign the future to a variable. The future's destructor is still run in all scenarios, just at different points in time. Remember that C++ cannot distinguish a function overload based on return type. That means, no matter if you use the return value or not, it will still be constructed and therefore has to be destructed. The only difference is when the destruction happens.
Scenario (a) is different, because both async calls happen synchronously, since the future is destroyed immediately, which blocks the thread:
{
async( []{ f(); } );
// ^ this future is a temporary, it will be destroyed here, directly after the function call
async( []{ g(); } );
// ^ this future is a temporary, it will be destroyed here, directly after the function call
}
Scenario (b) on the other hand, both async calls can happen before either future is destroyed, because both futures only ever get destroyed after both async calls happened.
{
auto f1 = async( []{ f(); } );
auto f2 = async( []{ g(); } );
}
// ^ variables went out of scope here, both futures will be destroyed now