Commit 72d6a134 authored by Nadeem Vawda's avatar Nadeem Vawda

Merge #13159: Replace FileIO's quadratic-time buffer growth algorithm with a linear-time one.

Also fix the bz2 module, which suffered from the same problem.
parents 55c99119 d41a98bd
...@@ -1342,6 +1342,9 @@ Tools/Demos ...@@ -1342,6 +1342,9 @@ Tools/Demos
Extension Modules Extension Modules
----------------- -----------------
- Issue #13159: FileIO and BZ2Compressor/BZ2Decompressor now use a linear-time
buffer growth strategy instead of a quadratic-time one.
- Issue #10141: socket: Add SocketCAN (PF_CAN) support. Initial patch by - Issue #10141: socket: Add SocketCAN (PF_CAN) support. Initial patch by
Matthias Fuchs, updated by Tiago Gonçalves. Matthias Fuchs, updated by Tiago Gonçalves.
......
...@@ -116,22 +116,14 @@ catch_bz2_error(int bzerror) ...@@ -116,22 +116,14 @@ catch_bz2_error(int bzerror)
#define SMALLCHUNK BUFSIZ #define SMALLCHUNK BUFSIZ
#endif #endif
#if SIZEOF_INT < 4
#define BIGCHUNK (512 * 32)
#else
#define BIGCHUNK (512 * 1024)
#endif
static int static int
grow_buffer(PyObject **buf) grow_buffer(PyObject **buf)
{ {
/* Expand the buffer by an amount proportional to the current size,
giving us amortized linear-time behavior. Use a less-than-double
growth factor to avoid excessive allocation. */
size_t size = PyBytes_GET_SIZE(*buf); size_t size = PyBytes_GET_SIZE(*buf);
if (size <= SMALLCHUNK) return _PyBytes_Resize(buf, size + (size >> 3) + 6);
return _PyBytes_Resize(buf, size + SMALLCHUNK);
else if (size <= BIGCHUNK)
return _PyBytes_Resize(buf, size * 2);
else
return _PyBytes_Resize(buf, size + BIGCHUNK);
} }
......
...@@ -43,12 +43,6 @@ ...@@ -43,12 +43,6 @@
#define SMALLCHUNK BUFSIZ #define SMALLCHUNK BUFSIZ
#endif #endif
#if SIZEOF_INT < 4
#define BIGCHUNK (512 * 32)
#else
#define BIGCHUNK (512 * 1024)
#endif
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
int fd; int fd;
...@@ -572,15 +566,10 @@ new_buffersize(fileio *self, size_t currentsize ...@@ -572,15 +566,10 @@ new_buffersize(fileio *self, size_t currentsize
} }
} }
#endif #endif
if (currentsize > SMALLCHUNK) { /* Expand the buffer by an amount proportional to the current size,
/* Keep doubling until we reach BIGCHUNK; giving us amortized linear-time behavior. Use a less-than-double
then keep adding BIGCHUNK. */ growth factor to avoid excessive allocation. */
if (currentsize <= BIGCHUNK) return currentsize + (currentsize >> 3) + 6;
return currentsize + currentsize;
else
return currentsize + BIGCHUNK;
}
return currentsize + SMALLCHUNK;
} }
static PyObject * static PyObject *
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment