Grow the string buffer at a mildly exponential rate for the getc version

of get_line.  This makes test_bufio finish in 1.7 seconds instead of 57
seconds on my machine (with Py_DEBUG defined).

Also, rename the local variables n1 and n2 to used_v_size and
total_v_size.
This commit is contained in:
Neil Schemenauer 2002-03-23 19:41:34 +00:00
parent ddea208be9
commit 3a204a7e48
1 changed files with 16 additions and 13 deletions

View File

@ -937,19 +937,21 @@ get_line(PyFileObject *f, int n)
FILE *fp = f->f_fp;
int c;
char *buf, *end;
size_t n1, n2;
size_t total_v_size; /* total # of slots in buffer */
size_t used_v_size; /* # used slots in buffer */
size_t increment; /* amount to increment the buffer */
PyObject *v;
#ifdef USE_FGETS_IN_GETLINE
if (n <= 0)
return getline_via_fgets(fp);
#endif
n2 = n > 0 ? n : 100;
v = PyString_FromStringAndSize((char *)NULL, n2);
total_v_size = n > 0 ? n : 100;
v = PyString_FromStringAndSize((char *)NULL, total_v_size);
if (v == NULL)
return NULL;
buf = BUF(v);
end = buf + n2;
end = buf + total_v_size;
for (;;) {
Py_BEGIN_ALLOW_THREADS
@ -979,23 +981,24 @@ get_line(PyFileObject *f, int n)
/* Must be because buf == end */
if (n > 0)
break;
n1 = n2;
n2 += 1000;
if (n2 > INT_MAX) {
used_v_size = total_v_size;
increment = total_v_size >> 2; /* mild exponential growth */
total_v_size += increment;
if (total_v_size > INT_MAX) {
PyErr_SetString(PyExc_OverflowError,
"line is longer than a Python string can hold");
Py_DECREF(v);
return NULL;
}
if (_PyString_Resize(&v, n2) < 0)
if (_PyString_Resize(&v, total_v_size) < 0)
return NULL;
buf = BUF(v) + n1;
end = BUF(v) + n2;
buf = BUF(v) + used_v_size;
end = BUF(v) + total_v_size;
}
n1 = buf - BUF(v);
if (n1 != n2)
_PyString_Resize(&v, n1);
used_v_size = buf - BUF(v);
if (used_v_size != total_v_size)
_PyString_Resize(&v, used_v_size);
return v;
}