From 3e56ff0d08a65ea1e0fe361ae22d855acc9d65bb Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Wed, 5 Oct 2016 18:01:12 -0400 Subject: [PATCH] Issue #28370: Speedup asyncio.StreamReader.readexactly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patch by Коренберг Марк. --- Lib/asyncio/streams.py | 32 +++++++++++++++----------------- Misc/NEWS | 3 +++ 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py index b4adc7d9c68..a82cc79acaa 100644 --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -448,6 +448,7 @@ class StreamReader: assert not self._eof, '_wait_for_data after EOF' # Waiting for data while paused will make deadlock, so prevent it. + # This is essential for readexactly(n) for case when n > self._limit. if self._paused: self._paused = False self._transport.resume_reading() @@ -658,25 +659,22 @@ class StreamReader: if n == 0: return b'' - # There used to be "optimized" code here. It created its own - # Future and waited until self._buffer had at least the n - # bytes, then called read(n). Unfortunately, this could pause - # the transport if the argument was larger than the pause - # limit (which is twice self._limit). So now we just read() - # into a local buffer. + while len(self._buffer) < n: + if self._eof: + incomplete = bytes(self._buffer) + self._buffer.clear() + raise IncompleteReadError(incomplete, n) - blocks = [] - while n > 0: - block = yield from self.read(n) - if not block: - partial = b''.join(blocks) - raise IncompleteReadError(partial, len(partial) + n) - blocks.append(block) - n -= len(block) + yield from self._wait_for_data('readexactly') - assert n == 0 - - return b''.join(blocks) + if len(self._buffer) == n: + data = bytes(self._buffer) + self._buffer.clear() + else: + data = bytes(self._buffer[:n]) + del self._buffer[:n] + self._maybe_resume_transport() + return data if compat.PY35: @coroutine diff --git a/Misc/NEWS b/Misc/NEWS index 8ea2ce23469..354dc59ca23 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -353,6 +353,9 @@ Library - Issue #28369: Raise RuntimeError when transport's FD is used with add_reader, add_writer, etc. +- Issue #28370: Speedup asyncio.StreamReader.readexactly. + Patch by Коренберг Марк. + IDLE ----