File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -12,6 +12,10 @@ What's New in Python 3.1 alpha 0
1212Core and Builtins
1313-----------------
1414
15+ - Issue #4533: File read operation was dreadfully slow due to a slowly
16+ growing read buffer. Fixed by using the same growth rate algorithm as
17+ Python 2.x.
18+
1519
1620Library
1721-------
Original file line number Diff line number Diff line change 2727#include <windows.h>
2828#endif
2929
30+ #if BUFSIZ < (8 * 1024 )
31+ #define SMALLCHUNK (8*1024)
32+ #elif (BUFSIZ >= (2 << 25 ))
33+ #error "unreasonable BUFSIZ > 64MB defined"
34+ #else
35+ #define SMALLCHUNK BUFSIZ
36+ #endif
37+
38+ #if SIZEOF_INT < 4
39+ #define BIGCHUNK (512 * 32)
40+ #else
41+ #define BIGCHUNK (512 * 1024)
42+ #endif
43+
3044typedef struct {
3145 PyObject_HEAD
3246 int fd ;
@@ -387,21 +401,30 @@ fileio_readinto(PyFileIOObject *self, PyObject *args)
387401 return PyLong_FromSsize_t (n );
388402}
389403
390- #define DEFAULT_BUFFER_SIZE (8*1024)
391-
392404static PyObject *
393405fileio_readall (PyFileIOObject * self )
394406{
395407 PyObject * result ;
396408 Py_ssize_t total = 0 ;
397409 int n ;
398410
399- result = PyBytes_FromStringAndSize (NULL , DEFAULT_BUFFER_SIZE );
411+ result = PyBytes_FromStringAndSize (NULL , SMALLCHUNK );
400412 if (result == NULL )
401413 return NULL ;
402414
403415 while (1 ) {
404- Py_ssize_t newsize = total + DEFAULT_BUFFER_SIZE ;
416+ Py_ssize_t newsize = (total < SMALLCHUNK ) ? SMALLCHUNK : total ;
417+
418+ /* Keep doubling until we reach BIGCHUNK;
419+ then keep adding BIGCHUNK. */
420+ if (newsize <= BIGCHUNK ) {
421+ newsize += newsize ;
422+ }
423+ else {
424+ /* NOTE: overflow impossible due to limits on BUFSIZ */
425+ newsize += BIGCHUNK ;
426+ }
427+
405428 if (PyBytes_GET_SIZE (result ) < newsize ) {
406429 if (_PyBytes_Resize (& result , newsize ) < 0 ) {
407430 if (total == 0 ) {
You can’t perform that action at this time.
0 commit comments