mirror of
				https://github.com/python/cpython.git
				synced 2025-10-25 02:43:41 +00:00 
			
		
		
		
	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
					
				
					 1 changed files with 16 additions and 9 deletions
				
			
		|  | @ -48,16 +48,17 @@ invalid_comma_type(Py_UCS4 presentation_type) | |||
|     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 kind = PyUnicode_KIND(str); | ||||
|     void *data = 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(kind, data, pos)); | ||||
|         if (digitval < 0) | ||||
|             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) { | ||||
|             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 @@ parse_internal_render_format_spec(PyObject *format_spec, | |||
|                                   char default_align) | ||||
| { | ||||
|     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
 | ||||
|        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; | ||||
|     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 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; | ||||
|     remainder = pos; | ||||
| 
 | ||||
|     /* 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. */ | ||||
|     if (*has_decimal) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Serhiy Storchaka
						Serhiy Storchaka