Skip to content

Commit

Permalink
extmod/uasyncio: Attempt to write immediately in Stream.write method.
Browse files Browse the repository at this point in the history
The main aim of this change is to reduce the number of heap allocations
when writing data to a stream.  This is done in two ways:

1. Eliminate appending of data when .write() is called multiple times
   before calling .drain().  With this commit, the data is written out
   immediately if the underlying stream is not blocked, so there is no
   accumulation of the data in a temporary buffer.

2. Eliminate copying of non-bytes objects passed to .write().  Prior to
   this commit, passing a bytearray or memoryview to .write() would always
   result in a copy of it being made and turned into a bytes object.  That
   won't happen now if the underlying stream is not blocked.

Also, this change makes .write () more closely implement the CPython
documented semantics: "The method attempts to write the data to the
underlying socket immediately.  If that fails, the data is queued in an
internal write buffer until it can be sent."
  • Loading branch information
tve authored and dpgeorge committed Jun 24, 2022
1 parent ba21f76 commit c21452a
Showing 1 changed file with 10 additions and 0 deletions.
10 changes: 10 additions & 0 deletions extmod/uasyncio/stream.py
Expand Up @@ -56,9 +56,19 @@ async def readline(self):
return l

def write(self, buf):
if not self.out_buf:
# Try to write immediately to the underlying stream.
ret = self.s.write(buf)
if ret == len(buf):
return
if ret is not None:
buf = buf[ret:]
self.out_buf += buf

async def drain(self):
if not self.out_buf:
# Drain must always yield, so a tight loop of write+drain can't block the scheduler.
return await core.sleep_ms(0)
mv = memoryview(self.out_buf)
off = 0
while off < len(mv):
Expand Down

0 comments on commit c21452a

Please sign in to comment.