[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [Libevent-users] event vs bufferevent

On 07/23/12 07:00, Filipe Miguel Campos Santos wrote:
> I know that for writing Data, bufferevents are more suitable because you
> need some kind of Output-Buffer from where Data ist partially drained  to
> the Socket every time the Socket gets ready for writing.
> But why should someone use bufferevents over events while just reading
> Data? Isnt the use of Events, where an application reads Data directly
> from a "ready to read" Socket more efficient, instead of using a
> Bufferevent which reads the data into the Input-Buffer where afterwards
> the application needs to drain the Data from that Input Buffer again?
> So, why using Bufferevents over Events to read Data? What are the reasons?

   Buffervents (when reading):
   1) Help parse streaming protocols, particularly line based, such as http.
   2) Avoid memmove()'s and buffer _re_allocations (i.e. grow buffers).
   3) Reuse already allocated memory as much as possible (I think.
Before I used bufferevents in libevent, I had my own library which did
the same thing, and one major point was buffer re-usage. I simply assume
that libevent does the same -- someone correct me if I'm wrong).

   If the protocol you're working with is streamable  (you can't in
advance know what you're getting, and/or it's infeasible to read
everything into memory), bufferevents help you read, parse and discard
the data, and it does so without internally moving around data
excessively (this last bit is an important point).

   In particular, say you're parsing a line-bases protocol, like http.
You can't in advance know how long a line is, so you start by allocating
a 256 byte buffer, read as much you can into it. You get X bytes, find
an EOL at Y bytes, where Y<X. So you process the line in your buffer,
and now you want to discard the processed line and read more data into
the buffer, after the data at index X. So to make more room for new data
you memmove() X-Y bytes from Y to the beginning of the buffer, and read
as much you can to the appropriate offset.

   Another case is when you've read 256 bytes and you haven't found an
EOL, so you need to expand the buffer you realloc() it, and the heap
can't expand the buffer, so it has to relocate it, which causes a memcpy().

   Consider how expensive these operations can turn out to be if they
happen a lot, and you'll understand the motivation for designing the
bufferevents. That said, they aren't a catch-all solution. If your
protocol is more deterministic; for instance if other side sends packets
exactly X bytes in size, packets are needed in their entirety, and they
fit into memory without any problems, etc, then I see little use for
reading them into bufferevents.

Kind regards,
Jan Danielsson

Attachment: signature.asc
Description: OpenPGP digital signature