lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Mon, Aug 25, 2014 at 4:38 PM, Sean Conner <sean@conman.org> wrote:

>   The suckb.lua script does allocate the buffer once, and it is of a fixed
> size.  The __len() function returns the currently used amount of the buffer.

Oh I know this -- I just thought your comparison was based on how
quickly you can write to the buffer and process it meaningfully (which
is a fair benchmark), but when I said "efficiently" I meant there are
times when you might be so constrained by memory that you cannot
afford to duplicate the recv() buffer by duplicating it into a string
you can then process/parse.  Conceptually, being able to read and
mutate userdata directly without creating "string clones" seems more
efficient.  I still want to take a closer look at this benchmark
though -- IT"S NOT OVER MY DEAR SEAN! BUWHAHAHAHAHAHAhahhahaha.  haha.
ha.

>   Fair criticism, and fixed in the repo.  I hoisted the definitions out of
> the main loop, and for suckb.lua, I made sure that data was declared local.
> I reran the tests but the results were similar as before.

Blah, I didn't think it would account for much -- but I still hoped
for a magic difference :-)

>   There are four functions you can use to read data from a socket:
>
>         read()
>         recv()
>         recvfrom()
>         recvmsg()
>
>   read() is fine for TCP and for "connected" UDP sockets [1], but for
> unconnected TCP (or even packets for other IP protocols like OSPF) you can't
> use read().  That's one reason I rejected using read().

Secret:  You can associate the remote peer (sockaddr) with a UDP
socket by calling connect() -- after that I believe you can call
read() like normal.  The man page says you can only connect() once for
TCP sockets, but you can call connect() multiple times for UDP
sockets.  This results in the kernel associating the remote peer with
that socket in the networking stack -- outwardly it doesn't seem to
have any effect.  People think because you only have an fd (an int)
that nothing happened -- buwhahaha bsd socket juju.  I know for sure
is how you can use recv() instead of recvfrom() on a UDP socket.

>   Harder than it sounds.  One thougt I did have was to "tweak" the type byte
> in the common header from LUA_TUSERDATA to LUA_TSTRING, but then I looked at
> the defintions of both strings and userdata:
>
> typedef union TString {
>   L_Umaxalign dummy;  /* ensures maximum alignment for strings */
>   struct {
>     CommonHeader;
>     lu_byte reserved;
>     unsigned int hash;
>     size_t len;
>   } tsv;
> } TString;
>
> typedef union Udata {
>   L_Umaxalign dummy;  /* ensures maximum alignment for ocal' udata */
>   struct {
>     CommonHeader;
>     struct Table *metatable;
>     struct Table *env;
>     size_t len;
>   } uv;
> } Udata;
>
>   You *MIGHT* get away with that on a 32-bit system where sizeof(pointer) ==
> sizeof(int) == sizeof(lu_byte + padding) and nothing touches the hash,
> metatable or env fields of either structure.  But on a 64-bit system, I
> woudn't count on sizeof(tsv) (from TString) being equal to sizeof(uv) (from
> Udata).

Hmm this will take some time for me to understand :>  Thanks for
finding the relevant bits for me <3