
On Sun, Jun 25, 2017 at 4:42 PM, Niall Douglas via Boost <boost@lists.boost.org> wrote: Rarely I find the need to quote myself, this is one such occasion:
Using gsl::span<> effectively type-erases the buffer sequence which is inefficient, since it must be copied to a vector equivalent in order to be used.
Think gsl::span<gsl::span<char>>.
gsl::span<gsl::span<char>> effectively requires the callers to set aside storage for an array of std::pair<void const*, std::size_t>. The Asio equivalent is std::vector<boost::asio::const_buffer> which as you can see is inefficient as std::vector is not cheap to copy. Asio's ConstBufferSequence concept of course includes gsl::span<gsl::span<char>> and std::vector<boost::asio::const_buffer> as models but it also includes the types I provided which cannot be modeled using gsl::span without intermediate storage. If you feel this is an acceptable tradeoff for your library, I am quite happy for you but I'll stick with the use of templates and the ConstBufferSequence concept since that is what is on track for standardization.
I'd have thought that as the HTTP comes in - in chunks - your code would work with discontiguous storage.
I thought that too and built quite a bit on top of a parser that worked in chunks, until I used a profiler and did some comparisons to other implementations...
Are you memory copying instead?
...when I discovered it is actually much, much faster to memcpy discontiguous buffers into a new, allocated buffer so that the parser can assume the entire structured portion is in a single "span" (to use the terminology you prefer). And of course if the caller already has the data in a single buffer then there's no need to memcpy. The class beast::flat_buffer is provided for that purpose.