Python no es C...
… y las cosas no se hacen igual.
Este post tiene su origen, como tantos otros, en cosas triviales: Leía el libro “Rapid GUI programming with Python and QT” (que interesante soy :P) cuando me topé con una instrucción que no conocía: unichr(i). Este built-in devuelve el carácter unicode que representa el entero i.
Por simple curiosidad hice un pequeño script que guardase en un fichero los caracteres unicode del 1 al 65536. Como aún arrastro muchos vicios de C, resultó en lo siguiente:
salida=u""
f = open("/tmp/unicode-slow.txt", "w")
for t in xrange(1, 65535):
salida = salida + u",%s" % unichr(t)
f.write(salida.encode("utf-8"))
f.close()
Típico, iterar por todos los valores de los caracteres unicode a representar e ir concatenándolos a una cadena.
Este script en mi portátil (G4@1.2Ghz) tarda la friolera de 1 minuto y 33 segundos en ejecutarse… Un SSH a mi equipo de sobremesa (Q6600@2.4Ghz) muestra que ahí tarda 5.31 segundos.
Ante estas cifras no pude menos que ponerme a pensar en la forma de rebajar tiempos, y me di cuenta de que la culpa de esa cantidad tan brutal de segundos la tiene mi empeño en programar “The C way” en lugar de “The Python way”.
Así que la nueva versión resulta:
salida=u""
f = open("/tmp/unicode-fast-list.txt", "w")
salida = [unichr(t) for t in xrange(1, 65535)]
f.write(",".join(salida).encode("utf-8") )
f.close()
“Uhmmmm… si uso un un generador en lugar de una lista podría rascar algo de tiempo”. Así que la versión definitiva queda como:
salida=u""
f = open("/tmp/unicode-fast-generator.txt", "w")
salida = (unichr(t) for t in xrange(1, 65535))
f.write(",".join(salida).encode("utf-8") )
f.close()
(En efecto, solo cambian los corchetes por paréntesis)
La diferencia de tiempo de ejecución entre los tres scripts es tan bruta, que prefiero mostrarla gráficamente:
¡En mi portátil, las nuevas versiones son 344 y 404 veces más rápida que la antigua! (93s/0.27s y 93s/0.23s, respectivamente). En el sobremesa esta diferencia se queda en “solo” 129 y 151 veces más veloz.
Para apreciar la diferencia entre los métodos más rápidos:
A pesar de que la diferencia entre la versión de lista y el generador no parece muy grande, 0.04 segundos es una eternidad para una CPU :)
Así que la moraleja de la historia es… se consecuente con el lenguaje de programación que usas, y serás más feliz :P
Gráficas creadas con Create a graph



Comentarios
Con algo así hemos conseguido rebajar los tiempos de carga en WordPress 2.6 :)
Nos estamos pasando todos a the python way.
Friki, muy Friki Soulnet. Pero en verdad llevas razón apañero.
Habrá que echarle un vistazo “the python way”
Enviar un comentario nuevo