Receive data from socket stream
Jean-Paul Calderone
exarkun at divmod.com
Mon Apr 28 09:58:50 EDT 2008
On Mon, 28 Apr 2008 08:30:03 -0500, Nick Craig-Wood <nick at craig-wood.com> wrote:
>Hrvoje Niksic <hniksic at xemacs.org> wrote:
>> Nick Craig-Wood <nick at craig-wood.com> writes:
>>
>> > What you are missing is that if the recv ever returns no bytes at all
>> > then the other end has closed the connection. So something like this
>> > is the correct thing to write :-
>> >
>> > data = ""
>> > while True:
>> > new = client.recv(256)
>> > if not new:
>> > break
>> > data += new
>>
>> This is a good case for the iter() function:
>>
>> buf = cStringIO.StringIO()
>> for new in iter(partial(client.recv, 256), ''):
>> buf.write(new)
>> data = buf.getvalue()
>>
>> Note that appending to a string is almost never a good idea, since it
>> can result in quadratic allocation.
>
>My aim was clear exposition rather than the ultimate performance!
>
>Anyway str += was optimised in python 2.4 or 2.5 (forget which) wasn't
>it? I'm not convinced it will be any worse performing than
>cStringIO.StringIO.write() which effectively appends to a string in
>exactly the same way.
>
>This test agrees with me!
>
>$ python -m timeit -s 's = ""' 'for i in xrange(100000): s+="x"'
>10 loops, best of 3: 23.8 msec per loop
>
>$ python -m timeit -s 'from cStringIO import StringIO; s=StringIO()' 'for i in xrange(100000): s.write("x")'
>10 loops, best of 3: 56 msec per loop
>
It's a bit nice that using cStringIO doesn't rely on a very esoteric
optimization in the CPython eval loop, as well as on what references
happen to exist to what objects. For example, one might want to use a
debugger without falling back to the quadratic behavior of repeated
string concatenation. cStringIO wins out in this case.
Jean-Paul
More information about the Python-list
mailing list