[Libwebsockets] lws_write speed

Andy Green andy at warmcat.com
Tue May 17 02:43:07 CEST 2016



On 05/17/2016 03:33 AM, Pierre Laplante wrote:
> In the example of the server, you are using malloc to copy the data
> before using lws_write as in:
>
> ...
>
>     out = (char /)malloc(sizeof(char)/(LWS_SEND_BUFFER_PRE_PADDING + len
>     + LWS_SEND_BUFFER_POST_PADDING));
>     memcpy (out + LWS_SEND_BUFFER_PRE_PADDING, str, len );
>     n = lws_write(wsi_in, out + LWS_SEND_BUFFER_PRE_PADDING, len,
>     LWS_WRITE_TEXT);
>
> If the buffer is very large, this copy all the data for almost nothing here.
>
> because of that, libwebsocket is very slow. In fact an ajax based
> solution is twice as fast as websocket.
>
> Is there another way to do this ?

You asked the same question here

https://github.com/warmcat/libwebsockets/issues/529

and I pointed out this is an architectural decision by lws-mirror 
protocol, you can allocate the storage some other way, if your data is 
coming from somewhere else (like a file) or is already in memory, no 
such management is needed.

But it also occurred to me maybe it looks to you like if you have a lot 
of data to send, you should shove it all down lws_write() in one go. 
That's not the right way to deal with it.

With a threaded / blocking system, the write() will accept some amount 
and then block... it will wake each time there is some new space and 
send a little more until it's all gone.  So the normal way there is just 
give the whole buffer, which may be huge, to write() and let it deal 
with it.

But with a single-threaded / event driven system the goal is to make 
sure it never blocks.  If the OS isn't able to accept your whole buffer 
on the socket, actually lws steps in and copies the rest into a buffer 
and auto-drains it, emulating the threaded model (and consequently 
making everything infefficient, if functional).  But that's a backup for 
emergencies, needed because there is no way to know how much the socket 
will accept until after you did the write, it's not how it should work.

How it should work is write stuff in chunks that are usually accepted by 
the socket, for example 2KB or 4KB.  You can do that once per WRITEABLE 
callback, and if there's more, ask to be called back when writable.  If 
the system is otherwise idle and more can be written, you'll be called 
back immediately.

-Andy

>
>
> _______________________________________________
> Libwebsockets mailing list
> Libwebsockets at ml.libwebsockets.org
> http://libwebsockets.org/mailman/listinfo/libwebsockets
>



More information about the Libwebsockets mailing list