2009-07-04 10 views
7

Estoy trabajando en el entorno de Google App Engine y la programación en Python. Estoy creando una función que esencialmente genera un número aleatorio/cadena de letras y luego almacena en la Memcache.¿La creación de funciones separadas en lugar de uno grande demora el tiempo de procesamiento?

def generate_random_string(): 
# return a random 6-digit long string 

def check_and_store_to_memcache(): 
    randomstring = generate_random_string() 
    #check against memcache 
    #if ok, then store key value with another value 
    #if not ok, run generate_random_string() again and check again. 

¿La creación de dos funciones en lugar de solo una grande afecta el rendimiento? Prefiero dos, ya que se ajusta mejor a cómo pienso, pero no me importa combinarlos si esa es la "mejor práctica".

+0

Puede sangrar con 4 espacios para que el código se visualice correctamente. –

Respuesta

28

Concéntrese en poder leer y comprender fácilmente su código.

Una vez que haya hecho esto, si tiene un problema de rendimiento, entonces investigue qué podría estar causándole.

La mayoría de los lenguajes, incluidos los de Python, tienden a tener una sobrecarga bastante baja para realizar llamadas a métodos. Poner este código en una sola función no cambiará (drásticamente) las métricas de rendimiento, supongo que la generación de números aleatorios será la mayor parte del tiempo, sin tener 2 funciones.

Dicho esto, las funciones de división tienen un impacto (muy, muy leve) en el rendimiento. Sin embargo, lo pensaría de esta manera: puede llevarlo de ir 80 mph en la carretera a 79.99 mph (lo que nunca notará realmente). Las cosas importantes a tener en cuenta son evitar los semáforos y los atascos de tráfico, ya que harán que tengas que parar por completo ...

+0

+1, muy buen consejo. –

+5

No mencionó que la optimización prematura crea más problemas de los que resuelve. –

+0

Sin embargo, sí trabajó en una sólida analogía con el automóvil. +1 por estilo! – Eric

4

Reed tiene razón. Para el cambio que está considerando, el costo de una llamada a función es un número pequeño de ciclos, y tendría que hacerlo 10^8 o menos veces por segundo antes de darse cuenta.

Sin embargo, me gustaría advertir que a menudo las personas van al otro extremo, y luego es como si las llamadas a la función fueran costosas. Lo he visto en sistemas sobrediseñados donde había muchas capas de abstracción.

Lo que sucede es que hay una psicología humana que dice que si algo es fácil de llamar, entonces es rápido. Esto lleva a escribir más llamadas a función de las estrictamente necesarias, y cuando esto ocurre en múltiples capas de abstracción, el desperdicio puede ser exponencial.

Siguiendo el ejemplo de la conducción de Reed, una llamada de función puede ser como un desvío, y si el desvío contiene desvíos, y si los contienen también desvíos, pronto hay un enorme tiempo que se desperdicia, ya que ningún obvia razón, porque cada función llamada parece inocente.

14

En casi todos los casos, las funciones "internas" para aumentar la velocidad son como cortarse el cabello para perder peso.

+8

++ ¡Gran metáfora! –

2

Al igual que otros han dicho, no me preocuparía en este escenario en particular. La muy pequeña sobrecarga involucrada en las llamadas a funciones palidecería en comparación con lo que se hace dentro de cada función. Y mientras estas funciones no se llamen en sucesión rápida, probablemente no importará mucho de todos modos.

Sin embargo, es una buena pregunta. En algunos casos, es mejor no dividir el código en varias funciones. Por ejemplo, cuando se trabaja con tareas intensivas en matemática con bucles anidados, es mejor hacer la menor cantidad posible de llamadas de función en el bucle interno. Esto se debe a que las operaciones de matemáticas simples son muy baratas, y junto a eso, la llamada a la función llamada puede causar una penalización notable en el rendimiento.

Hace años descubrí que la función de hipotenusa (hipotenusa) en la biblioteca de matemáticas que estaba usando en una aplicación de VC++ era muy lenta.Me pareció ridículo porque es un conjunto de funcionalidades tan simple - return sqrt (a * a + b * b) - ¿qué tan difícil es eso? Así que escribí el mío y logré mejorar el rendimiento 16 veces. Luego agregué la palabra clave "en línea" a la función y la hice 3 veces más rápida que eso (aproximadamente 50 veces más rápido en este punto). Luego saqué el código de la función y lo puse en mi propio bucle y vi otro pequeño incremento en el rendimiento. Entonces ... sí, esos son los tipos de escenarios donde se puede ver la diferencia.

+0

¿No sería sqrt (a * a + b * b)? –

+0

Ah sí, buena captura. –

Cuestiones relacionadas