Re: Socket performance
On 25-Jul-2010, at 5:52 PM, Roy Smith wrote: > In article <4c4bd0b1$0$1624$742ec...@news.sonic.net>, > John Nagle wrote: > >>1. When writing to a TCP socket, write everything you have to write >>with one "send" or "write" operation if at all possible. >>Don't write a little at a time. That results in sending small >>packets, because sockets are "flushed" after each write. > > There's nothing that guarantees that a single write won't be split into > multiple packets, nor that multiple writes won't be coalesced into a > single packet. Or any combination of splitting and coalescing that the > kernel feels like. > > That being said, for any sane implementation, what John says is true > most of the time, and is indeed a reasonable optimization. Just don't > depend on it being true all the time. The most common case where it > will not be true is if you're trying to send a large amount of data and > exceed the MTU of the network. Then you are certain to get > fragmentation. > > Depending on what you're doing, this can be a point of networking > trivia, or it can be the difference between your application working and > not working. If you're just streaming data from one place to another, > you don't have to worry about it. But, if you're doing some sort of > interactive protocol where you send a command, wait for a respond, send > another command, etc, you really do need to be aware of how this works. > > Let's say you're writing something like a HTTP client. You send a bunch > of headers, then expect to get back something like "200 OK\r\n", or "404 > Not Found\r\n". You can't just do a read() on the socket and then > examine the string to see if the first three characters are "200" or > "404", because (regardless of how the server sent them), it is legal for > your read() to return just a single character (i.e. "2"), and then for > the next read() to get "00 OK\r\n". You need to do buffering inside > your application which keeps doing read() until you find the "\r\n" (and > stops there, even if the read() returned more data beyond that). > -- > http://mail.python.org/mailman/listinfo/python-list Thanks John, Roy. I really appreciate your valuable input. I have made a note of what you have said and will implement keeping the same in mind : ) Nav -- http://mail.python.org/mailman/listinfo/python-list
Re: Socket performance
In article <4c4bd0b1$0$1624$742ec...@news.sonic.net>, John Nagle wrote: > 1. When writing to a TCP socket, write everything you have to write > with one "send" or "write" operation if at all possible. > Don't write a little at a time. That results in sending small > packets, because sockets are "flushed" after each write. There's nothing that guarantees that a single write won't be split into multiple packets, nor that multiple writes won't be coalesced into a single packet. Or any combination of splitting and coalescing that the kernel feels like. That being said, for any sane implementation, what John says is true most of the time, and is indeed a reasonable optimization. Just don't depend on it being true all the time. The most common case where it will not be true is if you're trying to send a large amount of data and exceed the MTU of the network. Then you are certain to get fragmentation. Depending on what you're doing, this can be a point of networking trivia, or it can be the difference between your application working and not working. If you're just streaming data from one place to another, you don't have to worry about it. But, if you're doing some sort of interactive protocol where you send a command, wait for a respond, send another command, etc, you really do need to be aware of how this works. Let's say you're writing something like a HTTP client. You send a bunch of headers, then expect to get back something like "200 OK\r\n", or "404 Not Found\r\n". You can't just do a read() on the socket and then examine the string to see if the first three characters are "200" or "404", because (regardless of how the server sent them), it is legal for your read() to return just a single character (i.e. "2"), and then for the next read() to get "00 OK\r\n". You need to do buffering inside your application which keeps doing read() until you find the "\r\n" (and stops there, even if the read() returned more data beyond that). -- http://mail.python.org/mailman/listinfo/python-list
Re: Socket performance
On 7/23/2010 5:06 PM, Navkirat Singh wrote: Hey Everyone, I had a question, programming sockets, what are the things that would degrade performance and what steps could help in a performance boost? I would also appreciate being pointed to some formal documentation or article. 1. When writing to a TCP socket, write everything you have to write with one "send" or "write" operation if at all possible. Don't write a little at a time. That results in sending small packets, because sockets are "flushed" after each write. 2. Wait for input from multiple sources by using "select". (But be aware that "select" doesn't work for Windows pipes.) John Nagle -- http://mail.python.org/mailman/listinfo/python-list
Re: Socket performance
On 25-Jul-2010, at 6:45 AM, Lawrence D'Oliveiro wrote: > In message > , Navkirat Singh wrote: > >> I had a question, programming sockets, what are the things that would >> degrade performance and what steps could help in a performance boost? > > Remember the old saying, “premature optimization is the root of all evil”. > > Have you actually got some code working properly first, before worrying > about how good or bad its performance is? > > -- > Lawrence > trying not to say “performant” :) > -- > http://mail.python.org/mailman/listinfo/python-list I agree with you, it was just for the sake of knowledge. Its always good to have a map right? -- http://mail.python.org/mailman/listinfo/python-list
Re: Socket performance
In message , Navkirat Singh wrote: > I had a question, programming sockets, what are the things that would > degrade performance and what steps could help in a performance boost? Remember the old saying, “premature optimization is the root of all evil”. Have you actually got some code working properly first, before worrying about how good or bad its performance is? -- Lawrence trying not to say “performant” :) -- http://mail.python.org/mailman/listinfo/python-list
Re: Socket performance
Navkirat Singh wrote: Thanks for the info : ). I will look into it ! Right now I am having a strange problem. I am trying to use cookies and the import function returns an error: I am using python 3: from http import cookies *importError:* No module named http Is it my configuration or has something changed since the documentation was written? Sorry I might be asking too many question, I am pretty new to this stuff and kinda feel lost here and there : ( It works for me (Python 3.1.2). -- http://mail.python.org/mailman/listinfo/python-list
Re: Socket performance
Thanks for the info : ). I will look into it ! Right now I am having a strange problem. I am trying to use cookies and the import function returns an error: I am using python 3: from http import cookies importError: No module named http Is it my configuration or has something changed since the documentation was written? Sorry I might be asking too many question, I am pretty new to this stuff and kinda feel lost here and there : ( Thanks, Nav On 24-Jul-2010, at 6:34 AM, MRAB wrote: Navkirat Singh wrote: Hey Everyone, I had a question, programming sockets, what are the things that would degrade performance and what steps could help in a performance boost? I would also appreciate being pointed to some formal documentation or article. I am new to this. Interleaving processing and sending/receiving might reduce throughput because when you're processing the socket is idle (depending on how much buffering there is). You could do the socket stuff in another thread so that it's not waiting for the processing to finish while there is data available, and use a queue to transfer the data between that thread and the processing thread. -- http://mail.python.org/mailman/listinfo/python-list -- http://mail.python.org/mailman/listinfo/python-list
Re: Socket performance
Navkirat Singh wrote: Hey Everyone, I had a question, programming sockets, what are the things that would degrade performance and what steps could help in a performance boost? I would also appreciate being pointed to some formal documentation or article. I am new to this. Interleaving processing and sending/receiving might reduce throughput because when you're processing the socket is idle (depending on how much buffering there is). You could do the socket stuff in another thread so that it's not waiting for the processing to finish while there is data available, and use a queue to transfer the data between that thread and the processing thread. -- http://mail.python.org/mailman/listinfo/python-list
Re: Socket Performance
On Mar 16, 1:29 pm, "Gabriel Genellina" <[EMAIL PROTECTED]> wrote: > En Sat, 15 Mar 2008 20:08:05 -0200, <[EMAIL PROTECTED]> escribi�: > > > > > > > On Mar 15, 8:18 am, Bryan Olson <[EMAIL PROTECTED]> wrote: > >> [EMAIL PROTECTED] wrote: > >> > Newbie question: Can you write to the 'file-like object' a pickle, > >> > and receive it intact-- as one string with nothing else? > > >> Yes, but there's a world of gotcha's. Sockets do not recognize > >> record boundaries, and Python's 'pickle' has holes one's enemies > >> could drive a truck through. Still, you can pickle, write, read, > >> un-pickle, and get back your data intact. > > >> > I want to know because I want to send two pickles. > > >> "Two pickles" sounds like a tasty snack, but also suggests you may > >> be playing hopscotch in a minefield. This is a helpful group. Give > >> us more to go on, and you are likely to receive thousands of > >> dollars worth of consulting for free. > > > It depends on the situation. How generally applicable is this: > > > fun ListenerGeneric( port, factory, arrivedfun ): > > > which calls 'factory' on socketA.accept (and loops again), then > > arrivedfun( stringA ) on message complete detection. ?. It should > > start itself in a separate thread. > > > Or is this any better: > > > for x in connections(): > > startnewthreadwith x: > > for y in messages( x ): > > arrivedfun( y ) > > This looks like a SocketServer + ThreadingMixIn + a RequestHandler (your > factory). > But as B. Olson already pointed, pickles are unsafe. Worse, it's not that > someone could send a specially crafted pickle that could execute some > arbitrary code: you're blindy executing whatever you receive! > xmlrpc may be a good alternative in some cases. I see. Just transmit a binary and execute that. Make sure to have handles to your program publicly accessible too. I execute this. -- http://mail.python.org/mailman/listinfo/python-list
Re: Socket Performance
En Sat, 15 Mar 2008 20:08:05 -0200, <[EMAIL PROTECTED]> escribi�: > On Mar 15, 8:18 am, Bryan Olson <[EMAIL PROTECTED]> wrote: >> [EMAIL PROTECTED] wrote: >> > Newbie question: Can you write to the 'file-like object' a pickle, >> > and receive it intact-- as one string with nothing else? >> >> Yes, but there's a world of gotcha's. Sockets do not recognize >> record boundaries, and Python's 'pickle' has holes one's enemies >> could drive a truck through. Still, you can pickle, write, read, >> un-pickle, and get back your data intact. >> >> > I want to know because I want to send two pickles. >> >> "Two pickles" sounds like a tasty snack, but also suggests you may >> be playing hopscotch in a minefield. This is a helpful group. Give >> us more to go on, and you are likely to receive thousands of >> dollars worth of consulting for free. > > It depends on the situation. How generally applicable is this: > > fun ListenerGeneric( port, factory, arrivedfun ): > > which calls 'factory' on socketA.accept (and loops again), then > arrivedfun( stringA ) on message complete detection. ?. It should > start itself in a separate thread. > > Or is this any better: > > for x in connections(): >startnewthreadwith x: > for y in messages( x ): > arrivedfun( y ) This looks like a SocketServer + ThreadingMixIn + a RequestHandler (your factory). But as B. Olson already pointed, pickles are unsafe. Worse, it's not that someone could send a specially crafted pickle that could execute some arbitrary code: you're blindy executing whatever you receive! xmlrpc may be a good alternative in some cases. -- Gabriel Genellina -- http://mail.python.org/mailman/listinfo/python-list
Re: Socket Performance
On Mar 15, 8:18 am, Bryan Olson <[EMAIL PROTECTED]> wrote: > [EMAIL PROTECTED] wrote: > > Gabriel Genellina wrote: > >> No need to reinvent the wheel. socket objects already have a makefile > >> method returning a file-like object, which behaves like a buffered socket. > > That wheel is far from round, and needs some reinvention. Python's > file-like objects do not play nice with lower level calls, which > would be tolerable if they supported some well-defiend high-level > asynchronous I/O, but they do not. > > > Newbie question: Can you write to the 'file-like object' a pickle, > > and receive it intact-- as one string with nothing else? > > Yes, but there's a world of gotcha's. Sockets do not recognize > record boundaries, and Python's 'pickle' has holes one's enemies > could drive a truck through. Still, you can pickle, write, read, > un-pickle, and get back your data intact. > > > I want to know because I want to send two pickles. > > "Two pickles" sounds like a tasty snack, but also suggests you may > be playing hopscotch in a minefield. This is a helpful group. Give > us more to go on, and you are likely to receive thousands of > dollars worth of consulting for free. It depends on the situation. How generally applicable is this: fun ListenerGeneric( port, factory, arrivedfun ): which calls 'factory' on socketA.accept (and loops again), then arrivedfun( stringA ) on message complete detection. ?. It should start itself in a separate thread. Or is this any better: for x in connections(): startnewthreadwith x: for y in messages( x ): arrivedfun( y ) -- http://mail.python.org/mailman/listinfo/python-list
Re: Socket Performance
[EMAIL PROTECTED] wrote: > Gabriel Genellina wrote: >> No need to reinvent the wheel. socket objects already have a makefile >> method returning a file-like object, which behaves like a buffered socket. That wheel is far from round, and needs some reinvention. Python's file-like objects do not play nice with lower level calls, which would be tolerable if they supported some well-defiend high-level asynchronous I/O, but they do not. > Newbie question: Can you write to the 'file-like object' a pickle, > and receive it intact-- as one string with nothing else? Yes, but there's a world of gotcha's. Sockets do not recognize record boundaries, and Python's 'pickle' has holes one's enemies could drive a truck through. Still, you can pickle, write, read, un-pickle, and get back your data intact. > I want to know because I want to send two pickles. "Two pickles" sounds like a tasty snack, but also suggests you may be playing hopscotch in a minefield. This is a helpful group. Give us more to go on, and you are likely to receive thousands of dollars worth of consulting for free. -- --Bryan -- http://mail.python.org/mailman/listinfo/python-list
Re: Socket Performance
On Mar 15, 3:33 am, "Gabriel Genellina" <[EMAIL PROTECTED]> wrote: > En Thu, 13 Mar 2008 15:18:44 -0200, <[EMAIL PROTECTED]> escribió: > > > Well, lets say you have a situation where you're going to be > > alternating between sending large and small chunks of data. Is the > > solution to create a NetworkBuffer class and only call send when the > > buffer is full, always recv(8192)? > > No need to reinvent the wheel. socket objects already have a makefile > method returning a file-like object, which behaves like a buffered socket. Newbie question: Can you write to the 'file-like object' a pickle, and receive it intact-- as one string with nothing else? I want to know because I want to send two pickles. -- http://mail.python.org/mailman/listinfo/python-list
Re: Socket Performance
En Thu, 13 Mar 2008 15:18:44 -0200, <[EMAIL PROTECTED]> escribió: > Well, lets say you have a situation where you're going to be > alternating between sending large and small chunks of data. Is the > solution to create a NetworkBuffer class and only call send when the > buffer is full, always recv(8192)? No need to reinvent the wheel. socket objects already have a makefile method returning a file-like object, which behaves like a buffered socket. -- Gabriel Genellina -- http://mail.python.org/mailman/listinfo/python-list
Re: Socket Performance
[EMAIL PROTECTED] wrote: > Well, lets say you have a situation where you're going to be > alternating between sending large and small chunks of data. Is the > solution to create a NetworkBuffer class and only call send when the > buffer is full, always recv(8192)? Buffering can often improve performance, but with the above we'd to too quick to prematurely jump to an as yet unwarranted conclusion. You measured the one-large and many-small cases, but not the case you actually have. You might be able to take various measurements and generally characterize speed as a function of the number of calls and the size of the send. I wouldn't be surprised if the result is well approximated by a time per call plus a time per byte. In optimization, guessing is bad. Where you cannot reason with mathematical rigor, measure. Where you can derive a purely analytic result, taking the occasional measurements still isn't a bad idea (but don't tell my algorithms students). -- --Bryan -- http://mail.python.org/mailman/listinfo/python-list
Re: Socket Performance
[EMAIL PROTECTED] wrote: [Dennis Lee Bieber had written:] >> Or create a protocol where the first 16 bits (in network byte order) >> contain a length value for the subsequent data, and use a receive >> process that consists of: >> >> leng = ntoh(socket.recv(2)) >> data = socket.receive(leng) >> >> (the send can combine the length with the data into a single packet) > > Are two 'sends' guaranteed to arrive as at least two 'receives'? No. Nor are they guaranteed to arrive as at least most two. > Send-3: xxx > Send-3: yyy > Receive-6: xxxyyy Can happen, though I think the problem with Dennis's code is the other way. The recv in leng = ntoh(socket.recv(2)) might return one byte of data, not two. The latter recv is similar. -- --Bryan -- http://mail.python.org/mailman/listinfo/python-list
Re: Socket Performance
> > Well, lets say you have a situation where you're going to be > > alternating between sending large and small chunks of data. Is the > > solution to create a NetworkBuffer class and only call send when the > > buffer is full, always recv(8192)? > > Or create a protocol where the first 16 bits (in network byte order) > contain a length value for the subsequent data, and use a receive > process that consists of: > > leng = ntoh(socket.recv(2)) > data = socket.receive(leng) > > (the send can combine the length with the data into a single packet) Are two 'sends' guaranteed to arrive as at least two 'receives'? Send-3: xxx Send-3: yyy Receive-6: xxxyyy -- http://mail.python.org/mailman/listinfo/python-list
Re: Socket Performance
On 2008-03-13, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote: >> > For example: try creating a local client/server (running on the same >> > computer) where the server sends the client a fixed amount of data. >> > Using method A, recv(8192) and sendall( ) with 8192 bytes >> > worth of data. Do this 100 times. Using method B, recv(1) and >> > sendall( ) with 1 byte worth of data. Do this 819200 times. >> >> > If you time both methods, method A has much greater >> > throughput than method B. >> >> Why is it faster to drink a liter of water a cupful at a time than to >> drink it out of an eyedropper? > Well, lets say you have a situation where you're going to be > alternating between sending large and small chunks of data. Is the > solution to create a NetworkBuffer class and only call send when the > buffer is full, always recv(8192)? If you need to send large and small chumks of data, the solution is to send large and small chunks of data. -- Grant -- http://mail.python.org/mailman/listinfo/python-list
Re: Socket Performance
On Mar 13, 9:33 am, "Brian Smith" <[EMAIL PROTECTED]> wrote: > [EMAIL PROTECTED] wrote: > > Sent: Wednesday, March 12, 2008 9:47 PM > > To: [EMAIL PROTECTED] > > Subject: Socket Performance > > > Can anyone explain why socket performance (throughput) varies > > depending on the amount of data send and recv are called with? > > > For example: try creating a local client/server (running on the same > > computer) where the server sends the client a fixed amount of data. > > Using method A, recv(8192) and sendall( ) with 8192 bytes > > worth of data. Do this 100 times. Using method B, recv(1) and > > sendall( ) with 1 byte worth of data. Do this 819200 times. > > > If you time both methods, method A has much greater > > throughput than method B. > > Why is it faster to drink a liter of water a cupful at a time than to > drink it out of an eyedropper? > > - Brian Well, lets say you have a situation where you're going to be alternating between sending large and small chunks of data. Is the solution to create a NetworkBuffer class and only call send when the buffer is full, always recv(8192)? -- http://mail.python.org/mailman/listinfo/python-list
RE: Socket Performance
[EMAIL PROTECTED] wrote: > Sent: Wednesday, March 12, 2008 9:47 PM > To: python-list@python.org > Subject: Socket Performance > > Can anyone explain why socket performance (throughput) varies > depending on the amount of data send and recv are called with? > > For example: try creating a local client/server (running on the same > computer) where the server sends the client a fixed amount of data. > Using method A, recv(8192) and sendall( ) with 8192 bytes > worth of data. Do this 100 times. Using method B, recv(1) and > sendall( ) with 1 byte worth of data. Do this 819200 times. > > If you time both methods, method A has much greater > throughput than method B. Why is it faster to drink a liter of water a cupful at a time than to drink it out of an eyedropper? - Brian -- http://mail.python.org/mailman/listinfo/python-list