[ZODB-Dev] zeo2a1 performance cold spots

Jeremy Hylton jeremy@alum.mit.edu
Sat, 29 Jun 2002 21:18:13 -0400


> Index: smac.py
> ===================================================================
> RCS file: /cvs-repository/Packages/ZEO/smac.py,v
> retrieving revision 1.17
> diff -c -2 -r1.17 smac.py
> *** smac.py     11 Jun 2002 13:43:06 -0000      1.17
> --- smac.py     29 Jun 2002 19:01:13 -0000
> ***************
> *** 139,142 ****
> --- 139,145 ----
>           while output:
>               v = output[0]
> +             while len(output)>1 and len(v)<16384:
> +                 del output[0]
> +                 v += output[0]
>               try:
>                   n=self.send(v)

It is definitely more efficient to do "".join(output) than to repeatedly
concatenate.  Each concatenate creates a new string and copies the contents
of the old strings into it, which has quadratic cost.

Also, why limit it to 16384?  Is that the TCP default buffer size?  I'd
rather let send() decide how many bytes it can buffer than choose an
arbitrary limit.

I'd also like to omit the TCP_NODELAY for now, as it's generally considered
a measure of last resort.  What kind of performance difference do you see?

The other effect you were seeing, BTW, is that TCP delays ACKs in hopes of
piggybacking the ACK on a packet with data in it.  The ACK can be delayed as
long as 200ms; at that point, the stack will send an ACK even if it has no
data to send.  This can lead to bad effects for an RPC system.  The RPC
request takes more than one packet.  If the Nagle algorithm delays the last
packet then the ACK will also be delayed, because the receiver won't send
any response data until the entire message has been procssed.

Jeremy