On Tue, Jul 11, 2017 at 5:08 PM, Andrey Semashev via Boost
I can argue that there is no such thing as too much performance. There's a balance with maintainability and other concerns, but as long as other requirements are satisfied, more performance is always welcome. And in many areas performance is the key point, so having faster code would certainly help the adoption.
I'd like to support Vinnie in his willingness to write and maintain code with the aim at performance. (Of course, as long as the performance is actually improved according to benchmarks.)
I have spent relatively little time optimizing specific areas of Beast. The parts I invested some time in were those parts which showed very obvious opportunities for non-trival improvements, when measured with a profiler. Although I am certain there are plenty more optimizations yet to be discovered, I am in no rush to do so. An area which I HAVE spent some time in, is making sure that Beast's interfaces do not inhibit future optimization from taking place. Stream and buffer algorithms are designed to allocate memory as minimally as possible. For algorithms that require memory allocation, the interface permits caller provided allocators to be passed. This extends especially to the asynchronous interfaces, which use the asio_handler_allocate, asio_handler_deallocate hooks. For example, I have developed a special allocator called "session_alloc" which wraps your completion handlers to customize the allocation hooks, and also functions as a standard Allocator for your containers and buffers. You create a new session_alloc allocator for each connection, and after a quick "warm-up" period where it learns the allocation requirements for the heaviest allocating call chain, future asynchronous operations become zero-alloc: https://github.com/vinniefalco/Beast/blob/25efdf1ba2b1f2f12781597c4a953a4989... This type of optimization is possible because of diligent adherence to Asio best practices and being mindful of customization points. Anything that Beast does which you don't like for performance reasons, you can usually replace. You can use your own Allocator with basic_fields, or implement your own Fields. You can use your own stream algorithm using basic_parser or serializer. You can derive from basic_parser and represent messages different ways, and Beast's stream read algorithms will still work for you. Beast is designed as a flexible, customizable set of tools you can use to assemble your own solution the way that you want.