8000 Speedup StreamReader.readexactly(). · python/asyncio@b0e7438 · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on Nov 23, 2017. It is now read-only.

Commit b0e7438

Browse files
socketpair1st1
authored andcommitted
Speedup StreamReader.readexactly().
1 parent e7a1078 commit b0e7438

File tree

1 file changed

+17
-19
lines changed

1 file changed

+17
-19
lines changed

asyncio/streams.py

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ def _wait_for_data(self, func_name):
448448
assert not self._eof, '_wait_for_data after EOF'
449449

450450
# Waiting for data while paused will make deadlock, so prevent it.
451+
# This is essential for readexactly(n) for case when n > self._limit.
451452
if self._paused:
452453
self._paused = False
453454
self._transport.resume_reading()
@@ -658,25 +659,22 @@ def readexactly(self, n):
658659
if n == 0:
659660
return b''
660661

661-
# There used to be "optimized" code here. It created its own
662-
# Future and waited until self._buffer had at least the n
663-
# bytes, then called read(n). Unfortunately, this could pause
664-
# the transport if the argument was larger than the pause
665-
# limit (which is twice self._limit). So now we just read()
666-
# into a local buffer.
667-
668-
blocks = []
669-
while n > 0:
670-
block = yield from self.read(n)
671-
if not block:
672-
partial = b''.join(blocks)
673-
raise IncompleteReadError(partial, len(partial) + n)
674-
blocks.append(block)
675-
n -= len(block)
676-
677-
assert n == 0
678-
679-
return b''.join(blocks)
662+
while len(self._buffer) < n:
663+
if self._eof:
664+
incomplete = bytes(self._buffer)
665+
self._buffer.clear()
666+
raise IncompleteReadError(incomplete, n)
667+
668+
yield from self._wait_for_data('readexactly')
669+
670+
if len(self._buffer) == n:
671+
data = bytes(self._buffer)
672+
self._buffer.clear()
673+
else:
674+
data = bytes(self._buffer[:n])
675+
del self._buffer[:n]
676+
self._maybe_resume_transport()
677+
return data
680678

681679
if compat.PY35:
682680
@coroutine

0 commit comments

Comments
 (0)
0