On Mon, 28 Apr 2008 08:30:03 -0500, Nick Craig-Wood <[EMAIL PROTECTED]> wrote:
Hrvoje Niksic <[EMAIL PROTECTED]> wrote:
 Nick Craig-Wood <[EMAIL PROTECTED]> 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
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to