[Twisted-Python] Sending a long string/buffer without copying it
Jean-Paul Calderone
exarkun at divmod.com
Thu Sep 28 06:22:01 MDT 2006
On Thu, 28 Sep 2006 00:11:41 -0600, Brian Granger <ellisonbg.net at gmail.com> wrote:
>HI,
>
>In one of my Twisted based applications, I need to send large string
>and buffers. They can be 100's of MB's long (they come from large
>numpy arrays). I would like to be able to send them *without making
>any copies* in the process.
>
>This seems to be dificult with the way that certain parts of Twisted
>are written:
>
>in protocols.basic many of the sendString/sendLine method having
>things that make a copy of the string or line to be send:
>
> def sendLine(self, line):
> """Sends a line to the other end of the connection.
> """
> return self.transport.write(line + self.delimiter)
>
>If line is 100MB, this just made a second 100MB string. To make
>things worse, in my case a server needs to send this line to many
>clients that are connected. The line gets copied for each client! If
>I have 10 clients, I have nearly a GB worth of extra memory allocated
>for this temporary copy.
>
>This problem is easy solve at the protocol level: you just do separate
>writes for the delimiter and the line. Or if you are using a length
>prefixed protocol, write the length bytes and the string separately.
>
>BUT....
>
>Even if I do that, it appears that Twisted is making copies elsewhere
>- like in FileDescriptor.doWrite. So, how can I send something
>without making a copy? I don't mind making copies of slices, just not
>the whole thing.
Don't pass the entire thing to a single call to transport.write() (or
LineReceiver.sendLine). Instead, write a producer.
Jean-Paul
More information about the Twisted-Python
mailing list