On Thursday, July 23, 2015 12:01 AM, Niall Douglas wrote:
On 22 Jul 2015 at 11:12, TONGARI J wrote:
Quite a few people have disliked (a) the choice of future continuations over ASIO's async_result pattern and (b) the batch API. Those two observations have come up repeatedly - Bjorn and Robert on this list have both publicly found issue there, and neither was alone in their opinion.
I'm not dropping futures in favour of async_result - I don't think that helps ease of use because in file i/o you really do want strong i/o ordering, and you usually don't care about ordering much for network i/o. Forthcoming C++ 1z coroutines are also futures based, and that decision is not going to be reversed now. Futures are our future as it were.
async_result is more flexible and it allows the use of future, e.g. `s.async_xxx(..., asio::use_future)`, and you can customize your afio::use_future to use your lightweight futures. What's your real concern of async_result? The verbosity of specifying afio::use_future? Since you mentioned C++ 1z coroutines, the asio way actually allows zero-overhead adaption without using a future, e.g. see: https://github.com/jamboree/act
A good summary of why those who prefer async_result do so, thank you.
Is any performance reason in preferring strict future API to the callback style?
Historically futures were slower, and Chris said so repeatedly in N-papers to WG21.
I believe lightweight futures have eliminated the performance gap. I also have an extension to the Concurrency TS in that you can add as many const lvalue ref continuations as you like to lightweight futures, not just a single rvalue ref continuation as per the TS.
This effectively implements a single shot signals and slots implementation - you can install as many completion handlers as you like per future.
None of this answers your question of course. I will say that file i/o is often 10x-1,000,000x slower than network i/o, and the performance of handlers vs continuations is correspondingly unimportant.
Futures gives you the option of monadic programming, and they enforce strict operation ordering very succintly. They are the right choice for file i/o, just as async_result is the right choice for network i/o.
Though, to be honest, I suspect lightweight futures will make async_result not as useful as previously.
To clarify; I think you're saying that your lightweight futures are close enough to free that you would prefer to implement your library with them as opposed to callback hell; and so, presenting the nicer future API poses no significant further performance penalty whilst presenting a nicer syntactic model. Personally I'm really interested in your lightweight futures for the same reason. Callback hell sucks; without profile information to the contrary, I'd rather just write code the nice way. Ben