summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorhajoscher <hajoscher@gmail.com>2018-07-04 08:13:18 (GMT)
committerINADA Naoki <methane@users.noreply.github.com>2018-07-04 08:13:18 (GMT)
commit12a08c47601cadea8e7d3808502cdbcca87b2ce2 (patch)
tree18813841cb73ced22a5e12d338f241e49a84e1f1 /Lib
parent97ae32c92ecc7b3c29f8829a2b79f0f8f8bbf2cc (diff)
downloadcpython-12a08c47601cadea8e7d3808502cdbcca87b2ce2.zip
cpython-12a08c47601cadea8e7d3808502cdbcca87b2ce2.tar.gz
cpython-12a08c47601cadea8e7d3808502cdbcca87b2ce2.tar.bz2
bpo-34010: Fix tarfile read performance regression (GH-8020)
During buffered read, use a list followed by join instead of extending a bytes object. This is how it was done before but changed in commit b506dc32c1a.
Diffstat (limited to 'Lib')
-rwxr-xr-xLib/tarfile.py20
1 files changed, 11 insertions, 9 deletions
diff --git a/Lib/tarfile.py b/Lib/tarfile.py
index 7b4732d..59f044c 100755
--- a/Lib/tarfile.py
+++ b/Lib/tarfile.py
@@ -525,7 +525,7 @@ class _Stream:
if not buf:
break
t.append(buf)
- buf = "".join(t)
+ buf = b"".join(t)
else:
buf = self._read(size)
self.pos += len(buf)
@@ -538,6 +538,7 @@ class _Stream:
return self.__read(size)
c = len(self.dbuf)
+ t = [self.dbuf]
while c < size:
buf = self.__read(self.bufsize)
if not buf:
@@ -546,26 +547,27 @@ class _Stream:
buf = self.cmp.decompress(buf)
except self.exception:
raise ReadError("invalid compressed data")
- self.dbuf += buf
+ t.append(buf)
c += len(buf)
- buf = self.dbuf[:size]
- self.dbuf = self.dbuf[size:]
- return buf
+ t = b"".join(t)
+ self.dbuf = t[size:]
+ return t[:size]
def __read(self, size):
"""Return size bytes from stream. If internal buffer is empty,
read another block from the stream.
"""
c = len(self.buf)
+ t = [self.buf]
while c < size:
buf = self.fileobj.read(self.bufsize)
if not buf:
break
- self.buf += buf
+ t.append(buf)
c += len(buf)
- buf = self.buf[:size]
- self.buf = self.buf[size:]
- return buf
+ t = b"".join(t)
+ self.buf = t[size:]
+ return t[:size]
# class _Stream
class _StreamProxy(object):