extmod/uasyncio: Attempt to write immediately in Stream.write method.
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."
This commit is contained in:
parent
ba21f76f89
commit
c21452a1d2
|
@ -56,9 +56,19 @@ class Stream:
|
|||
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):
|
||||
|
|
Loading…
Reference in New Issue