Sustitución de cadenas vs concatenación en Python

Tenía la idea de que la sustitución de valores era más rápida que simplemente concatenar cadenas. Pero en Python tal parece que es al revés.

Probando con un caso —muy muy muy— extremo, de 1 millón de iteraciones tenemos resultados interesantes.

STRING1 = 'Esta es la '
STRING2 = 'iteracion numero: '
FINAL = ''

for i in xrange(0, 1000000):
  FINAL += STRING1 + STRING2 + str(i) + '\n'

Concatenando de esta manera el resultado de time es:

real 0m1.479s
user 0m1.396s
sys 0m0.081s

Y al cambiar casi todas las concatenaciones por sustituciones de esta manera:

for i in xrange(0, 1000000):
  FINAL += '%s%s %d\n' % (STRING1, STRING2, i)

Obtenemos estos tiempos:

real 0m1.830s
user 0m1.746s
sys 0m0.081s

Aquí la diferencia no es realmente significativa si tomamos en cuenta el enorme tamaño del bucle. Así que yo sigo prefiriendo no sacrificar la legibilidad del código y seguir utilizando sustituciones en lugar de concatenaciones.

Pero ojo, esto no es una sustitución completa. Si eliminamos la única concatenación que dejamos en el segundo código:

for i in xrange(0, 10000):
  FINAL = '%s %s%s %d\n' % (FINAL, STRING1, STRING2, i)

Con "apenas" 10,000 iteraciones, vamos a tener tiempos arriba de 2 segundos. Ya imaginarás como sube exponencialmente si aumentamos el rango. No se cual sea la razón, pero parece que no es buena idea sustituir miles de cadenas enormes.

real 0m2.043s
user 0m0.899s
sys 0m1.139s

Esta claro, si para ti es crítico el rendimiento; concatena, sino no hay problema con que utilices sustituciones.