[Zope-dev] Re: [Zope-Annce] ZEO 2.0 beta 1 released

2002-08-29 Thread Toby Dickenson

On Wednesday 28 Aug 2002 2:19 pm, Jeremy Hylton wrote:

 I'd like to change this bit of code in handle_write():

 if n  len(v):
 # XXX It's unfortunate that we end up making many
 # slices of a large string.
 output.insert(0, v[n:])
 break # we can't write any more

 If we send a very large message, which could be caused by a big pickle
 or just a transaction that touches a lot of objects, the message gets
 sent in little chunks.  The current implementation uses string slicing
 to save the rest of the string, but that ends up making many copies of
 the large string -- an O(n^2) proposition.

 A possible solution is to store an index into the first string in
 __output and just increment the index.  The logic will be a bit tricky
 to get right.

There is an O(n) option with easy logic... fragment big strings inside 
message_output.

diff attached.


[hmmm. Its use of a python list as a fifo queue is O(n2) worst case, but I 
doubt we will be affected by that in practice]


Index: smac.py
===
RCS file: /cvs-repository/Packages/ZEO/smac.py,v
retrieving revision 1.19
diff -c -4 -r1.19 smac.py
*** smac.py	22 Aug 2002 18:29:13 -	1.19
--- smac.py	29 Aug 2002 09:40:44 -
***
*** 133,140 
--- 133,145 
  return 0
  else:
  return 1
  
+ # We chose 6 as the socket limit by looking at the
+ # largest strings that we could pass to send() without
+ # blocking.
+ _write_chunk_size = 6
+ 
  def handle_write(self):
  output = self.__output
  while output:
  # Accumulate output into a single string so that we avoid
***
*** 144,159 
  # unfortunate interaction between the Nagle algorithm and
  # delayed acks.  If we send a very large string, only a
  # portion of it will actually be delivered at a time.
  
- # We chose 6 as the socket limit by looking at the
- # largest strings that we could pass to send() without
- # blocking.
- 
  l = 0
  for i in range(len(output)):
  l += len(output[i])
! if l  6:
  break
  
  i += 1
  # It is very unlikely that i will be 1.
--- 149,160 
  # unfortunate interaction between the Nagle algorithm and
  # delayed acks.  If we send a very large string, only a
  # portion of it will actually be delivered at a time.
  
  l = 0
  for i in range(len(output)):
  l += len(output[i])
! if l = self._write_chunk_size:
  break
  
  i += 1
  # It is very unlikely that i will be 1.
***
*** 189,198 
  This action is temporarily unavailable.
  p
  )
  # do two separate appends to avoid copying the message string
! self.__output.append(struct.pack(i, len(message)))
! self.__output.append(message)
  
  def close(self):
  if self.__closed is None:
  self.__closed = 1
--- 190,206 
  This action is temporarily unavailable.
  p
  )
  # do two separate appends to avoid copying the message string
! l = len(message)
! self.__output.append(struct.pack(i, l))
! if l = self._write_chunk_size:
! self.__output.append(message)
! else:
! # fragment large strings now, to avoid O(n2) behavior when
! # dealing with huge strings.
! for start in range(0,l,self._write_chunk_size):
! self.__output.append(message[start:start+self._write_chunk_size])
  
  def close(self):
  if self.__closed is None:
  self.__closed = 1



[Zope-dev] Re: [Zope-Annce] ZEO 2.0 beta 1 released

2002-08-29 Thread Jeremy Hylton

 TD == Toby Dickenson [EMAIL PROTECTED] writes:

  TD There is an O(n) option with easy logic... fragment big strings
  TD inside message_output.

Sounds like a possibility.  It would still be nice to have something
in handle_write() to avoid extra slicing on partial send()s.  But your
patch is nice and simple.

Jeremy


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



[Zope-dev] Re: [Zope-Annce] ZEO 2.0 beta 1 released

2002-08-28 Thread Jeremy Hylton

 TD == Toby Dickenson [EMAIL PROTECTED] writes:

   although we may do one more beta release to add some performance
   improvements.

  TD Do you have something specific in mind?

I'd like to change this bit of code in handle_write():

if n  len(v):
# XXX It's unfortunate that we end up making many
# slices of a large string.
output.insert(0, v[n:])
break # we can't write any more

If we send a very large message, which could be caused by a big pickle
or just a transaction that touches a lot of objects, the message gets
sent in little chunks.  The current implementation uses string slicing
to save the rest of the string, but that ends up making many copies of
the large string -- an O(n^2) proposition.

A possible solution is to store an index into the first string in
__output and just increment the index.  The logic will be a bit tricky
to get right.

   After the alpha release, I suggested that there would be several
   more alpha releases to add new features.  We didn't have the
   resources to pursue the new features.  Instead, we plan to get a
   solid 2.0 final release out as soon as possible.  New features
   will be postponed until
   2.1.

  TD I would like to merge the branch 'toby-signal-branch' in before
  TD 2.0. This provides an easy way to use extensions to the storage
  TD API across ZEO.

  TD This feature is critical for DirectoryStorage. I am 100% happy
  TD with the current implementation (but not very happy with the
  TD name of the new method suggestions welcome)

I'll look at the branch before the next beta.  Anyone have ideas for a
new name?

Jeremy




___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )