mirror of https://github.com/python/cpython.git
Issue #27818: Speed up parsing width and precision in format() strings for
numbers. Patch by Stefan Behnel.
This commit is contained in:
parent
8631da64bb
commit
1f9326196e
|
@ -48,16 +48,17 @@ invalid_comma_type(Py_UCS4 presentation_type)
|
||||||
returns -1 on error.
|
returns -1 on error.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
get_integer(PyObject *str, Py_ssize_t *pos, Py_ssize_t end,
|
get_integer(PyObject *str, Py_ssize_t *ppos, Py_ssize_t end,
|
||||||
Py_ssize_t *result)
|
Py_ssize_t *result)
|
||||||
{
|
{
|
||||||
Py_ssize_t accumulator, digitval;
|
Py_ssize_t accumulator, digitval, pos = *ppos;
|
||||||
int numdigits;
|
int numdigits;
|
||||||
|
int kind = PyUnicode_KIND(str);
|
||||||
|
void *data = PyUnicode_DATA(str);
|
||||||
|
|
||||||
accumulator = numdigits = 0;
|
accumulator = numdigits = 0;
|
||||||
for (;;(*pos)++, numdigits++) {
|
for (; pos < end; pos++, numdigits++) {
|
||||||
if (*pos >= end)
|
digitval = Py_UNICODE_TODECIMAL(PyUnicode_READ(kind, data, pos));
|
||||||
break;
|
|
||||||
digitval = Py_UNICODE_TODECIMAL(PyUnicode_READ_CHAR(str, *pos));
|
|
||||||
if (digitval < 0)
|
if (digitval < 0)
|
||||||
break;
|
break;
|
||||||
/*
|
/*
|
||||||
|
@ -69,10 +70,12 @@ get_integer(PyObject *str, Py_ssize_t *pos, Py_ssize_t end,
|
||||||
if (accumulator > (PY_SSIZE_T_MAX - digitval) / 10) {
|
if (accumulator > (PY_SSIZE_T_MAX - digitval) / 10) {
|
||||||
PyErr_Format(PyExc_ValueError,
|
PyErr_Format(PyExc_ValueError,
|
||||||
"Too many decimal digits in format string");
|
"Too many decimal digits in format string");
|
||||||
|
*ppos = pos;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
accumulator = accumulator * 10 + digitval;
|
accumulator = accumulator * 10 + digitval;
|
||||||
}
|
}
|
||||||
|
*ppos = pos;
|
||||||
*result = accumulator;
|
*result = accumulator;
|
||||||
return numdigits;
|
return numdigits;
|
||||||
}
|
}
|
||||||
|
@ -150,9 +153,11 @@ parse_internal_render_format_spec(PyObject *format_spec,
|
||||||
char default_align)
|
char default_align)
|
||||||
{
|
{
|
||||||
Py_ssize_t pos = start;
|
Py_ssize_t pos = start;
|
||||||
|
int kind = PyUnicode_KIND(format_spec);
|
||||||
|
void *data = PyUnicode_DATA(format_spec);
|
||||||
/* end-pos is used throughout this code to specify the length of
|
/* end-pos is used throughout this code to specify the length of
|
||||||
the input string */
|
the input string */
|
||||||
#define READ_spec(index) PyUnicode_READ_CHAR(format_spec, index)
|
#define READ_spec(index) PyUnicode_READ(kind, data, index)
|
||||||
|
|
||||||
Py_ssize_t consumed;
|
Py_ssize_t consumed;
|
||||||
int align_specified = 0;
|
int align_specified = 0;
|
||||||
|
@ -402,13 +407,15 @@ parse_number(PyObject *s, Py_ssize_t pos, Py_ssize_t end,
|
||||||
Py_ssize_t *n_remainder, int *has_decimal)
|
Py_ssize_t *n_remainder, int *has_decimal)
|
||||||
{
|
{
|
||||||
Py_ssize_t remainder;
|
Py_ssize_t remainder;
|
||||||
|
int kind = PyUnicode_KIND(s);
|
||||||
|
void *data = PyUnicode_DATA(s);
|
||||||
|
|
||||||
while (pos<end && Py_ISDIGIT(PyUnicode_READ_CHAR(s, pos)))
|
while (pos<end && Py_ISDIGIT(PyUnicode_READ(kind, data, pos)))
|
||||||
++pos;
|
++pos;
|
||||||
remainder = pos;
|
remainder = pos;
|
||||||
|
|
||||||
/* Does remainder start with a decimal point? */
|
/* Does remainder start with a decimal point? */
|
||||||
*has_decimal = pos<end && PyUnicode_READ_CHAR(s, remainder) == '.';
|
*has_decimal = pos<end && PyUnicode_READ(kind, data, remainder) == '.';
|
||||||
|
|
||||||
/* Skip the decimal point. */
|
/* Skip the decimal point. */
|
||||||
if (*has_decimal)
|
if (*has_decimal)
|
||||||
|
|
Loading…
Reference in New Issue