Closed kvanbere closed 10 years ago
Also, this is a good read: http://blog.libtorrent.org/2012/12/principles-of-high-performance-programs/
It's what got me curious to see if Haskell had vectored IO support.
@kvanberendonck thanks for bringing this up.
So, if I understand you correctly, the intention here is to add, alongside Network.Simple.TCP.send
, something like this which internally uses vectored IO:
sendMany :: MonadIO m => NS.Socket -> [BS.ByteString] -> m ()
Is that what you have on your mind?
Ah, my mistake. I did not see the braces in the type.
I got the impression since ByteStrings were chunked internally this would be a free performance upgrade to sending many chunks from a chunked BS. Maybe the performance win still exists, but it could be harder to attain.
Turns out lazy ByteStrings already have this support in network
.
http://hackage.haskell.org/package/network-2.3.0.11/docs/src/Network-Socket-ByteString-Lazy.html#send
(note the c_writev
).
There is no way to make strict Bytestrings faster with vectored IO unless you have a streaming library like, for example, pipes-group
. Sorry I closed this kind of too promptly. Reopen if you want to add support for vectored IO to network-simple
for lists of ByteStrings.
Still, I think it would be useful to export sendLazy :: MonadIO m => NS.Socket -> Lazy.ByteString -> m ()
from Network.Simple.TCP
, which does just that. A Lazy ByteString is, after all, pretty much a list of strict ByteStrings. What do you think?
It would be a good idea. If anything, to open up room for experimentation later.
Related to pipes-network
:
I wonder if it's possible to rig up pipes-network
to have a batching interface. Like, "run this pipe until it returns Nothing
and then send all the ByteString
s you get at once using vectored IO". This would make it extremely easy to wrap around the main packet processing loop of i.e. a game server, so if it needs to send 2-3 packets to the same socket in reaction to some message, they go out vectored (and you yield Nothing
once at the very end to "flush"..)
I don't think we should add that behaviour to pipes-network
as it seems quite specific to a particular use case and it can be confusing (and “not simple”, as in network-simple) to new users. Besides, you can already use send
(or this newly introduced sendLazy
) as a Pipes.Effect
without any lift
ing whatsoever, so in a sense you can already accomplish what you want, right?
Consider: https://github.com/k0001/network-simple/blob/master/src/Network/Simple/TCP.hs#L316
network
now has vectored IO: https://hackage.haskell.org/package/network-2.5.0.0/docs/Network-Socket-ByteString.html#g:2This will be faster on platforms supporting it.