Re: Socket performance

2010-07-25 Thread Roy Smith
In article 4c4bd0b1$0$1624$742ec...@news.sonic.net,
 John Nagle na...@animats.com 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

2010-07-25 Thread Navkirat Singh

On 25-Jul-2010, at 5:52 PM, Roy Smith wrote:

 In article 4c4bd0b1$0$1624$742ec...@news.sonic.net,
 John Nagle na...@animats.com 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

2010-07-24 Thread Lawrence D'Oliveiro
In message
mailman.1097.1279930004.1673.python-l...@python.org, 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

2010-07-24 Thread Navkirat Singh

On 25-Jul-2010, at 6:45 AM, Lawrence D'Oliveiro wrote:

 In message
 mailman.1097.1279930004.1673.python-l...@python.org, 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

2010-07-24 Thread John Nagle

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


Socket performance

2010-07-23 Thread Navkirat Singh

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.

Warm regards,
Nav
--
http://mail.python.org/mailman/listinfo/python-list


Re: Socket performance

2010-07-23 Thread MRAB

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

2010-07-23 Thread Navkirat Singh
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

2010-07-23 Thread MRAB

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

2008-03-16 Thread Gabriel Genellina
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

2008-03-16 Thread castironpi
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

2008-03-15 Thread Gabriel Genellina
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

2008-03-15 Thread castironpi
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

2008-03-15 Thread Bryan Olson
[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

2008-03-15 Thread castironpi
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

2008-03-14 Thread castironpi
  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

2008-03-14 Thread Bryan Olson
[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

2008-03-14 Thread Bryan Olson
[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

2008-03-13 Thread Brian Smith
[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


Re: Socket Performance

2008-03-13 Thread sleddd
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

2008-03-13 Thread Grant Edwards
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


Socket Performance

2008-03-12 Thread sleddd
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.

Server:

import socket
import random
import string
import time

HOST = 'localhost'
PORT = 50023
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr

string_1 = 'A'
string_8192 = ''.join([random.choice(string.letters + string.digits)
for i in range(8192)])

conn.sendall('Start')

start = time.clock()
total_data = 0
for i in range(0,100):
   conn.sendall(string_8192)
   total_data += len(string_8192)
print 'Send Speed (Long String): ' + str( total_data / (time.clock() -
start) / 1024 / 1024 ) + ' MB/sec\n\n'

start = time.clock()
total_data = 0
for i in range(0,819200):
   conn.sendall(string_1)
   total_data += len(string_1)
print 'Send Speed (Short String): ' + str( total_data / (time.clock()
- start) / 1024 / 1024 ) + ' MB/sec'

conn.close()


Client:

import socket
import time

HOST = 'localhost'# The remote host
PORT = 50023  # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, 50026))
s.connect((HOST, PORT))

data = s.recv(5)
print 'From Server: ' + data

start = time.clock()
total_data = 0
while total_data  819200:
   data = s.recv(8192)
   total_data += len(data)
print 'Receive Speed (Long String): ' + str( total_data /
(time.clock() - start) / 1024 / 1024 ) + ' MB/sec\n\n'

start = time.clock()
total_data = 0
while total_data  819200:
   data = s.recv(1)
   total_data += len(data)
print 'Receive Speed (Short String): ' + str( total_data /
(time.clock() - start) / 1024 / 1024 ) + ' MB/sec'
s.close()
-- 
http://mail.python.org/mailman/listinfo/python-list