Skip to content

Commit 8d4cdef

Browse files
author
chris.withers
committed
Fixes issue #6838: use a list to accumulate the value instead of repeatedly concatenating strings.
git-svn-id: http://svn.python.org/projects/python/branches/release31-maint@74662 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent 759fa93 commit 8d4cdef

2 files changed

Lines changed: 14 additions & 12 deletions

File tree

Lib/http/client.py

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -518,10 +518,7 @@ def read(self, amt=None):
518518
def _read_chunked(self, amt):
519519
assert self.chunked != _UNKNOWN
520520
chunk_left = self.chunk_left
521-
value = b""
522-
523-
# XXX This accumulates chunks by repeated string concatenation,
524-
# which is not efficient as the number or size of chunks gets big.
521+
value = []
525522
while True:
526523
if chunk_left is None:
527524
line = self.fp.readline()
@@ -534,22 +531,22 @@ def _read_chunked(self, amt):
534531
# close the connection as protocol synchronisation is
535532
# probably lost
536533
self.close()
537-
raise IncompleteRead(value)
534+
raise IncompleteRead(b''.join(value))
538535
if chunk_left == 0:
539536
break
540537
if amt is None:
541-
value += self._safe_read(chunk_left)
538+
value.append(self._safe_read(chunk_left))
542539
elif amt < chunk_left:
543-
value += self._safe_read(amt)
540+
value.append(self._safe_read(amt))
544541
self.chunk_left = chunk_left - amt
545-
return value
542+
return b''.join(value)
546543
elif amt == chunk_left:
547-
value += self._safe_read(amt)
544+
value.append(self._safe_read(amt))
548545
self._safe_read(2) # toss the CRLF at the end of the chunk
549546
self.chunk_left = None
550-
return value
547+
return b''.join(value)
551548
else:
552-
value += self._safe_read(chunk_left)
549+
value.append(self._safe_read(chunk_left))
553550
amt -= chunk_left
554551

555552
# we read the whole chunk, get another
@@ -570,7 +567,7 @@ def _read_chunked(self, amt):
570567
# we read everything; close the "file"
571568
self.close()
572569

573-
return value
570+
return b''.join(value)
574571

575572
def _safe_read(self, amt):
576573
"""Read the number of bytes requested, compensating for partial reads.

Misc/NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ C-API
5050
Library
5151
-------
5252

53+
- Issue #6838: Use a list to accumulate the value instead of
54+
repeatedly concatenating strings in http.client's
55+
HTTPResponse._read_chunked providing a significant speed increase
56+
when downloading large files servend with a Transfer-Encoding of 'chunked'.
57+
5358
- Have importlib raise ImportError if None is found in sys.modules for a
5459
module.
5560

0 commit comments

Comments
 (0)