2010-12-28 8 views
21

Solía ​​usar un buen generador de perfiles de Apple que está integrado en la aplicación Monitor del sistema. Siempre que su código C++ haya sido compilado con información de depuración, podrá muestrear la aplicación en ejecución e imprimir un árbol con sangría que le indicará qué porcentaje del tiempo de la función padre se gastó en esta función (y el cuerpo frente a otras llamadas a función) .¿Cómo se puede obtener el árbol de llamadas con los perfiles de python?

Por ejemplo, si principal llamado function_1 y function_2, function_2 llamadas function_3, y luego llama principales function_3:

main (100%, 1% in function body): 
    function_1 (9%, 9% in function body): 
    function_2 (90%, 85% in function body): 
     function_3 (100%, 100% in function body) 
    function_3 (1%, 1% in function body) 

me gustaría ver esto y pensar, "Algo está tomando mucho tiempo en el código en el cuerpo de function_2. Si quiero que mi programa sea más rápido, ahí es donde debería comenzar ".

¿Alguien sabe cómo puedo obtener más fácilmente esta salida de perfil exacta para un programa de Python?

He visto a gente decir que hacer esto:

import cProfile, pstats 
prof = cProfile.Profile() 
prof = prof.runctx("real_main(argv)", globals(), locals()) 
stats = pstats.Stats(prof) 
stats.sort_stats("time") # Or cumulative 
stats.print_stats(80) # 80 = how many to print 

pero es bastante complicado en comparación con el árbol de llamadas elegante. Por favor, avíseme si puede hacer esto fácilmente, sería bastante útil.

¡Salud!

Respuesta

9

Consulte esta biblioteca http://pycallgraph.slowchop.com/ para ver los gráficos de llamadas. Funciona realmente bien. Si desea perfilar funciones específicas, consulte http://mg.pov.lt/blog/profiling.html

Este es un resultado del módulo profilehooks.

alt text

+0

¿Sabe usted si este paquete pueden hacer transcurrido el tiempo, así como el número de llamadas a la función? Por ejemplo, no me importaría llamar a __hash __() miles de veces, pero llamar ordenado() repetidamente en listas grandes podría ser bastante lento. – user

+0

Deberías probar ambos. Básicamente hacen lo mismo de diferentes maneras con diferentes salidas. – Falmarri

+0

+1, el paquete está en línea con lo que tenía en mente y fue rápido y fácil de instalar y llamar. ¿Te importa decirme cómo obtuviste la figura anterior? Hice un gráfico (usando pycallgraph.start_trace() y pycallgraph.make_dot_graph ('test.jpg', format = 'jpg', tool = 'neato') ), pero está demasiado lleno y se oscurecen muchas funciones. – user

15

Hace poco quería lo mismo, por lo que tomó una puñalada en la implementación de uno mismo.

El proyecto está en Github. https://github.com/joerick/pyinstrument

Así es como usted lo utilizaría:

from pyinstrument import Profiler 

profiler = Profiler() 
profiler.start() 

# code you want to profile 

profiler.stop() 

print(profiler.output_text()) 
+1

¡Esto es fantástico, gracias! – Maximilian

+0

Parece agradable, aquí hay una que es más una biblioteca genérica: https://github.com/vmprof/vmprof-python – dashesy

+1

Esto es realmente genial, ¡gracias! – Dakkaron

38

Me tropecé en este también, y pasado algún tiempo aprender a generar un gráfico de llamadas (los resultados normales de cprofile no es muy informativo). Referencia futura, aquí hay otra forma de generar un hermoso gráfico de árbol de llamada con cProfile + gprof2dot + graphViz.

-------

  1. Instalar GraphViz: http://www.graphviz.org/Download_macos.php
  2. easy_install gprof2dot
  3. perfil Ejecutar en el código.

    python -m cProfile -o myLog.profile <myScript.py> arg1 arg2 ... 
    
  4. Run gprof2dot para convertir el perfil de llamada en un archivo de puntos

    gprof2dot -f pstats myLog.profile -o callingGraph.dot 
    
  5. abierta con Graphviz para visualizar el gráfico

Esto es lo que el resultado final sería así! El gráfico está codificado por color, rojo significa mayor concentración de tiempo.

Graph is color-coded- red means higher concentration of time

+4

[xdot] (https://pypi.python.org/pypi/xdot) es un buen visor interactivo para archivos .dot que le permite acercarse a cosas. –

+2

Puede mostrar el archivo .dot en Unix con un comando de shell como "dot callingGraph.dot -Tpng | display" en lugar del paso 5. – benjimin

+1

¡Gran respuesta, exactamente lo que estaba buscando, gracias! –

Cuestiones relacionadas