3 ms·
Ah, I loved coroutines. Combining this with Boost.ASIO and Boost.Beast, you can make a high-performance HTTP server/client in C++ quickly while defeating the co
by stevefan1999 7y ago
Ah, I loved coroutines. Combining this with Boost.ASIO and Boost.Beast, you can make a high-performance HTTP server/client in C++ quickly while defeating the competitors several margins far away.
Sadly, coroutine TS in Boost.ASIO is still a preview feature, and I've met a lot of quirks that stopped me forwarding from using it, for example, sockets have to be moved even inside a lambda, that can clearly optimized out by referencing, and I had some frustration of this.
- dnpp123 7y agoDo you have any benchmark to back this assertion by any chance ? The only benchmark I know of is https://www.techempower.com/benchmarks/ https://www.techempower.com/benchmarks/ which is really poorly done but it's better than nothing. Rust seems to sometimes come first and C++ framework are close (and not by several margins).
- ploxiln 7y agoThe benchmarks leader "actix-web" was not really regular/typical rust, and conflict with the "community" caused it to implode. see https://github.com/actix/actix-web/ https://github.com/actix/actix-web/ and https://news.ycombinator.com/item?id=22075076 https://news.ycombinator.com/item?id=22075076
- tsimionescu 7y agoStill, the fastest C++ framework there is slower than than both the fastest Go-based fwk and the fastest Java-based one.
- dnpp123 7y agoYes this is why I said the benchmark is poorly written. It encourages frameworks to do such thing. Even if you look at the code of hyper for the benchmark, it does some ugly things not recommended in production. I'm not blaming actix/hyper's authors, I'm blaming the benchmark author encouraging (not voluntarily) such practice. However the benchmark is enough to see that C++ is not faster by several margins, hence my curiosity about benchmarks proving otherwise.
- nly 7y agoWith a coroutine you may not necessarily have to do as many gymnastics as with callbacks. You can turn a push operation ("call me back using this function with a newly connected socket"), in to a pull operation ("get me a newly connected socket") For example, here's an awaitable that just wraps ASIO callback for accepting new connections: auto async_accept (tcp::acceptor& acceptor, tcp::socket& socket) { struct Awaitable { tcp::acceptor& acceptor; tcp::socket& socket; boost::system::error_code ec; bool await_ready() { return false; } void await_suspend (std::experimental::coroutine_handle<> coro) { return acceptor.async_accept ( socket, [this, coro](boost::system::error_code ec) mutable { this->ec = ec; coro.resume(); } ); } auto await_resume() { return ec; } }; return Awaitable{acceptor, socket}; };