# HG changeset patch # Parent bdfd4c8384de83eb9e7f71963928f758d2288e0c speed up int/float formatting by 5-20% by avoiding unnecessary overhead diff -r bdfd4c8384de Python/formatter_unicode.c --- a/Python/formatter_unicode.c Sat Aug 20 08:56:40 2016 -0700 +++ b/Python/formatter_unicode.c Sat Aug 20 21:41:12 2016 +0200 @@ -48,16 +48,17 @@ returns -1 on error. */ 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 accumulator, digitval; + Py_ssize_t accumulator, digitval, pos = *ppos; int numdigits; + int ukind = PyUnicode_KIND(str); + void *udata = PyUnicode_DATA(str); + accumulator = numdigits = 0; - for (;;(*pos)++, numdigits++) { - if (*pos >= end) - break; - digitval = Py_UNICODE_TODECIMAL(PyUnicode_READ_CHAR(str, *pos)); + for (;pos < end; pos++, numdigits++) { + digitval = Py_UNICODE_TODECIMAL(PyUnicode_READ(ukind, udata, pos)); if (digitval < 0) break; /* @@ -69,10 +70,12 @@ if (accumulator > (PY_SSIZE_T_MAX - digitval) / 10) { PyErr_Format(PyExc_ValueError, "Too many decimal digits in format string"); + *ppos = pos; return -1; } accumulator = accumulator * 10 + digitval; } + *ppos = pos; *result = accumulator; return numdigits; } @@ -150,9 +153,11 @@ char default_align) { Py_ssize_t pos = start; + int ukind = PyUnicode_KIND(format_spec); + void *udata = PyUnicode_DATA(format_spec); /* end-pos is used throughout this code to specify the length of the input string */ -#define READ_spec(index) PyUnicode_READ_CHAR(format_spec, index) +#define READ_spec(index) PyUnicode_READ(ukind, udata, index) Py_ssize_t consumed; int align_specified = 0; @@ -402,13 +407,15 @@ Py_ssize_t *n_remainder, int *has_decimal) { Py_ssize_t remainder; + int ukind = PyUnicode_KIND(s); + void *udata = PyUnicode_DATA(s); - while (pos