summaryrefslogtreecommitdiff
path: root/Lib/socket.py
diff options
context:
space:
mode:
authorKristján Valur Jónsson <kristjan@ccpgames.com>2009-06-02 13:14:08 +0000
committerKristján Valur Jónsson <kristjan@ccpgames.com>2009-06-02 13:14:08 +0000
commit36c3928fdc7d246fda50d48c108fb6116c315229 (patch)
treebeca449530d10af45e187e1571cdc7392149f558 /Lib/socket.py
parentd57b5543e42675f1d4c30326049de4f4fdf4ffc8 (diff)
downloadcpython-git-36c3928fdc7d246fda50d48c108fb6116c315229.tar.gz
http://bugs.python.org/issue6117
Fix O(n**2) performance problem in socket._fileobject
Diffstat (limited to 'Lib/socket.py')
-rw-r--r--Lib/socket.py19
1 files changed, 9 insertions, 10 deletions
diff --git a/Lib/socket.py b/Lib/socket.py
index e694587ea8..dd0f327a3a 100644
--- a/Lib/socket.py
+++ b/Lib/socket.py
@@ -235,7 +235,7 @@ class _fileobject(object):
__slots__ = ["mode", "bufsize", "softspace",
# "closed" is a property, see below
- "_sock", "_rbufsize", "_wbufsize", "_rbuf", "_wbuf",
+ "_sock", "_rbufsize", "_wbufsize", "_rbuf", "_wbuf", "_wbuf_len",
"_close"]
def __init__(self, sock, mode='rb', bufsize=-1, close=False):
@@ -261,6 +261,7 @@ class _fileobject(object):
# realloc()ed down much smaller than their original allocation.
self._rbuf = StringIO()
self._wbuf = [] # A list of strings
+ self._wbuf_len = 0
self._close = close
def _getclosed(self):
@@ -287,6 +288,7 @@ class _fileobject(object):
if self._wbuf:
buffer = "".join(self._wbuf)
self._wbuf = []
+ self._wbuf_len = 0
self._sock.sendall(buffer)
def fileno(self):
@@ -297,25 +299,22 @@ class _fileobject(object):
if not data:
return
self._wbuf.append(data)
+ self._wbuf_len += len(data)
if (self._wbufsize == 0 or
self._wbufsize == 1 and '\n' in data or
- self._get_wbuf_len() >= self._wbufsize):
+ self._wbuf_len >= self._wbufsize):
self.flush()
def writelines(self, list):
# XXX We could do better here for very long lists
# XXX Should really reject non-string non-buffers
- self._wbuf.extend(filter(None, map(str, list)))
+ lines = filter(None, map(str, list))
+ self._wbuf_len += sum(map(len, lines))
+ self._wbuf.extend(lines)
if (self._wbufsize <= 1 or
- self._get_wbuf_len() >= self._wbufsize):
+ self._wbuf_len >= self._wbufsize):
self.flush()
- def _get_wbuf_len(self):
- buf_len = 0
- for x in self._wbuf:
- buf_len += len(x)
- return buf_len
-
def read(self, size=-1):
# Use max, disallow tiny reads in a loop as they are very inefficient.
# We never leave read() with any leftover data from a new recv() call