mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	Optimize string_repeat.
Christian Tismer pointed out the high cost of the loop overhead and function call overhead for 'c' * n where n is large. Accordingly, the new code only makes lg2(n) loops. Interestingly, 'c' * 1000 * 1000 ran a bit faster with old code. At some point, the loop and function call overhead became cheaper than invalidating the cache with lengthy memcpys. But for more typical sizes of n, the new code runs much faster and for larger values of n it runs only a bit slower.
This commit is contained in:
		
							parent
							
								
									68b539ef9c
								
							
						
					
					
						commit
						698258a199
					
				
					 1 changed files with 11 additions and 2 deletions
				
			
		| 
						 | 
					@ -933,6 +933,7 @@ static PyObject *
 | 
				
			||||||
string_repeat(register PyStringObject *a, register int n)
 | 
					string_repeat(register PyStringObject *a, register int n)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	register int i;
 | 
						register int i;
 | 
				
			||||||
 | 
						register int j;
 | 
				
			||||||
	register int size;
 | 
						register int size;
 | 
				
			||||||
	register PyStringObject *op;
 | 
						register PyStringObject *op;
 | 
				
			||||||
	size_t nbytes;
 | 
						size_t nbytes;
 | 
				
			||||||
| 
						 | 
					@ -965,8 +966,16 @@ string_repeat(register PyStringObject *a, register int n)
 | 
				
			||||||
	PyObject_INIT_VAR(op, &PyString_Type, size);
 | 
						PyObject_INIT_VAR(op, &PyString_Type, size);
 | 
				
			||||||
	op->ob_shash = -1;
 | 
						op->ob_shash = -1;
 | 
				
			||||||
	op->ob_sstate = SSTATE_NOT_INTERNED;
 | 
						op->ob_sstate = SSTATE_NOT_INTERNED;
 | 
				
			||||||
	for (i = 0; i < size; i += a->ob_size)
 | 
						i = 0;
 | 
				
			||||||
		memcpy(op->ob_sval+i, a->ob_sval, (int) a->ob_size);
 | 
						if (i < size) {
 | 
				
			||||||
 | 
							memcpy(op->ob_sval, a->ob_sval, (int) a->ob_size);
 | 
				
			||||||
 | 
							i = (int) a->ob_size;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						while (i < size) {
 | 
				
			||||||
 | 
							j = (i <= size-i)  ?  i  :  size-i;
 | 
				
			||||||
 | 
							memcpy(op->ob_sval+i, op->ob_sval, j);
 | 
				
			||||||
 | 
							i += j;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	op->ob_sval[size] = '\0';
 | 
						op->ob_sval[size] = '\0';
 | 
				
			||||||
	return (PyObject *) op;
 | 
						return (PyObject *) op;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue