Documentación
Pyinstrument es un generador de perfiles de Python. Un generador de perfiles es una herramienta que le ayuda a optimizar su código y hacerlo más rápido. Para obtener el mayor aumento de velocidad, debes concentrarte en la parte más lenta de tu programa. ¡Pyinstrument te ayuda a encontrarlo!
☕️ ¿No estás seguro de por dónde empezar? ¡Mira este video tutorial de calmcode.io!
pip install pyinstrument
Pyinstrument es compatible con Python 3.8+.
Para ejecutar Pyinstrument desde un git checkout, hay un paso de compilación. Echa un vistazo a Contribuir para obtener más información.
Para aprender a usar pyinstrument o consultar la referencia, diríjase a la documentación.
pyinstrument script.py
donde script.py
contiene una clase serializada con pickle
, es posible que encuentre errores porque la maquinaria de serialización no sabe dónde está __main__
. Consulte este problema para encontrar soluciones 11 de octubre de 2024
¡Muchas mejoras en el renderizador HTML!
Modo de línea de tiempo: ¡vea y amplíe una línea de tiempo lineal interactiva!
El modo HTML ahora tiene opciones interactivas, en lugar de tener que configurarlas por adelantado.
Simplificó el diseño del encabezado de la página HTML.
La vista de pila de llamadas HTML admite la navegación con las teclas de flecha.
Se ha cambiado la forma en que se detecta el código de 'biblioteca'. Anteriormente, si la cadena '/lib/' aparecía en la ruta del archivo, se consideraba código de biblioteca (y se contraía de forma predeterminada). Ahora, pyinstrument captura las rutas de instalación de Python y cualquier entorno virtualenv/conda activo en el momento del perfil. Los archivos que se almacenan allí se consideran biblioteca. Eso debería dar menos falsos positivos.
Las llamadas a perfiler.start() ahora pueden pasar un parámetro target_description, que se muestra en la lectura del perfil.
Consulte la publicación de mi blog para obtener más información sobre las nuevas funciones.
6 de septiembre de 2024
glom
en Python 3.12 o posterior, lo que muta el dict locals(). (#336)UnicodeDecodeError
en algunas plataformas (#330)5 de agosto de 2024
2 de agosto de 2024
1 de agosto de 2024
with
o un decorador de función/método. Esto perfilará el código e imprimirá una breve lectura en el terminal. (#327)flat
a la salida de la consola para presentar una lista plana de funciones (#294)26 de enero de 2024
show_all
a Profiler.output_html8 de noviembre de 2023
%pyinstrument
(#278)12 de octubre de 2023
-c
, que permite crear perfiles de código directamente desde la línea de comando, como python -c
. (#271)Profiler.write_html
, para escribir resultados HTML en un archivo directamente. (#266)7 de septiembre de 2023
1 de septiembre de 2023
22 julio 2023
[X frames hidden]
en la salida cuando los cuadros se eliminaban debido a __tracebackhide__
(#255)None
en la salida de la consola (#254)5 de junio de 2023
-p flat
en la línea de comando. Este modo muestra el fotograma más pesado medido por el tiempo propio, lo que puede resultar útil en algunas bases de código. (#240)pstats
. Este es el formato de archivo utilizado por cprofile en stdlib. Es menos detallado que los perfiles de pyinstrument, pero es compatible con más herramientas. (#236)--show-all
: pyinstrument ya no eliminará los marcos internos de Python cuando se proporcione esta opción. (#239)5 de noviembre de 2022
__traceback_hide__
ahora se eliminarán de la salida (#217)--async_mode=enabled
. (#212)21 agosto 2022
--interval
(segundos, predeterminado 0.001) para cambiar el intervalo en el que pyinstrument muestrea un programa. Esto es útil para programas de larga duración, donde aumentar el intervalo reduce la sobrecarga de memoria. Agrega una opción de línea de comando -p
--render-option
que permite la configuración arbitraria de las opciones de renderizado. Esto le permite configurar opciones como filter_threshold
desde la línea de comando, haciendo algo como pyinstrument -p processor_options.filter_threshold=0
.
Aquí está el resultado de ayuda para la opción:
-p RENDER_OPTION, --render-option=RENDER_OPTION
options to pass to the renderer, in the format
'flag_name' or 'option_name=option_value'. For
example, to set the option 'time', pass '-p
time=percent_of_total'. To pass multiple options, use
the -p option multiple times. You can set processor
options using dot-syntax, like '-p
processor_options.filter_threshold=0'. option_value is
parsed as a JSON value or a string.
Agrega la capacidad de ver los tiempos en la salida de la consola como porcentajes, en lugar de tiempos absolutos. Utilice la opción ConsoleRenderer time='percent_of_total'
o, en la línea de comando, utilice -p
, como pyinstrument -p time=percent_of_total
.
Agrega opciones de línea de comando para cargar y guardar sesiones de pyinstrument. Puede guardar los datos sin procesar para una sesión de pyinstrument con -r session
, como pyinstrument -r session -o session.pyisession myscript.py
. La carga se realiza a través de --load
, por ejemplo, pyinstrument --load session.pyisession
.
El formato de salida de la línea de comando se infiere de la extensión del archivo de salida -o
. Entonces, si haces pyinstrument -o profile.html myscript.py
, no necesitas proporcionar -r html
, pyinstrument usará automáticamente el procesador HTML. O si lo haces pyinstrument -o profile.pyisession myscript.py
, guardará un objeto de sesión sin formato.
Agrega ejemplos de uso para FastAPI y pytest a la documentación.
Corrige un error que causa NotImplementedError cuando se usa async_mode=strict
.
Agrega soporte para Python 3.11
%load_ext pyinstrument
en la parte superior de su cuaderno y luego %%pyinstrument
en la celda cuyo perfil desea crear.pyinstrument -r speedscope
y cárguelo en la aplicación web speedscope.PYINSTRUMENT_PROFILE_DIR_RENDERER
.¡Soporte asíncrono! Pyinstrument ahora detecta cuando una tarea asíncrona llega a una espera y rastrea el tiempo pasado fuera del contexto asíncrono bajo esta espera.
Entonces, por ejemplo, aquí hay un script simple con una tarea asíncrona que duerme:
import asyncio
from pyinstrument import Profiler
async def main ():
p = Profiler ( async_mode = 'disabled' )
with p :
print ( 'Hello ...' )
await asyncio . sleep ( 1 )
print ( '... World!' )
p . print ()
asyncio . run ( main ())
Antes de Pyinstrument 4.0.0, solo veíamos el tiempo transcurrido en el ciclo de ejecución, así:
_ ._ __/__ _ _ _ _ _/_ Recorded: 18:33:03 Samples: 2
/_//_/// /_ / //_// / //_'/ // Duration: 1.006 CPU time: 0.001
/ _/ v3.4.2
Program: examples/async_example_simple.py
1.006 _run_once asyncio/base_events.py:1784
└─ 1.005 select selectors.py:553
[3 frames hidden] selectors,
1.005 kqueue.control :0
Ahora, con pyinstrument 4.0.0, obtenemos:
_ ._ __/__ _ _ _ _ _/_ Recorded: 18:30:43 Samples: 2
/_//_/// /_ / //_// / //_'/ // Duration: 1.007 CPU time: 0.001
/ _/ v4.0.0
Program: examples/async_example_simple.py
1.006 main async_example_simple.py:4
└─ 1.005 sleep asyncio/tasks.py:641
[2 frames hidden] asyncio
1.005 [await]
Para obtener más información, consulte la documentación de creación de perfiles asíncronos y la propiedad Profiler.async_mode.
Pyinstrument tiene un sitio de documentación, que incluye documentos completos de la API de Python.
--show
, --show-regex
, --show-all
fueran ignorados en la línea de comando.timeline
(booleana) a los métodos de Profiler output_html()
y open_in_browser()
.pyinstrument -m module
, donde pyinstrument no encontraba módulos en el directorio actual.Python -> C -> Python
se registra como Python -> Python
, pero Python -> Python -> C
se atribuirá correctamente. (#103)<__array_function__ internals>
que aparecen como código de aplicación en los informes.--show
y --show-regex
para marcar ciertos archivos que se mostrarán. Esto ayuda a crear perfiles dentro de módulos específicos, mientras oculta otros. Por ejemplo, pyinstrument --show '*/sympy/*' script.py
.Pyinstrument ahora ocultará los rastros a través de las bibliotecas que estás usando de forma predeterminada. Entonces, en lugar de mostrarle un montón de cuadros que atraviesan el interior de algo externo, por ejemplo, urllib, le permite concentrarse en su código.
Antes | Después |
---|---|
Para volver al comportamiento anterior, utilice --show-all
en la línea de comando.
Se muestran marcos de 'entrada' de grupos ocultos, para que sepas qué llamada es el problema
También se muestran fotogramas realmente lentos en los grupos, por ejemplo, la llamada de "lectura" en el socket.
El código de la aplicación está resaltado en la consola.
Se muestran métricas adicionales en la parte superior del seguimiento: marca de tiempo, número de muestras, duración, tiempo de CPU.
El código oculto está controlado por las opciones --hide
o --hide-regex
, que coinciden con la ruta de los archivos de código.
--hide=EXPR glob-style pattern matching the file paths whose
frames to hide. Defaults to '*/lib/*'.
--hide-regex=REGEX regex matching the file paths whose frames to hide.
Useful if --hide doesn't give enough control.
Se admite la generación de una línea de tiempo desde la línea de comando.
-t, --timeline render as a timeline - preserve ordering and don't
condense repeated calls
Debido a que ahora hay algunas opciones de renderizado, puede cargar una sesión de generación de perfiles anterior usando --load-prev
- pyinstrument mantiene las últimas 10 sesiones.
Los grupos ocultos también pueden volver a llamar al código de la aplicación, que se ve así:
(interno) Al grabar líneas de tiempo, los árboles de cuadros ahora son completamente lineales, lo que permite la creación de gráficos de cuadros súper precisos.
(interno) El procesador HTML se ha reescrito como una aplicación Vue.js. Todas las mejoras de la consola también se aplican a la salida HTML y además es interactiva.
(interno) ¡Se agregaron muchas pruebas unitarias y de integración!
¡Ay! Consulte el n.° 49 para conocer los detalles sangrientos. Espero que te guste.
Recorders
. La grabación del cuadro ahora es interna al objeto Profiler
. Esto significa que los objetos de 'marco' son de uso más general, lo que allana el camino para...--version
Se agregó soporte para salida JSON. Utilice pyinstrument --renderer=json scriptfile.py
. relaciones públicas
¡@iddan ha creado un visor interactivo utilizando la salida JSON!
Cuando ejecuta pyinstrument --html
y no canaliza la salida a un archivo, pyinstrument escribirá la salida de la consola en un archivo temporal y lo abrirá en un navegador.
-m
, por ejemplo, pyinstrument -m module_name
. relaciones públicas Pyinstrument ahora se puede utilizar en un bloque with
.
Por ejemplo:
profiler = pyinstrument.Profiler()
with profiler:
# do some work here...
print(profiler.output_text())
Solución de middleware para versiones anteriores de Django
Pyinstrument utiliza un nuevo modo de creación de perfiles . En lugar de utilizar señales, pyintrument utiliza un nuevo generador de perfiles estadísticos creado en PyEval_SetProfile. ¡Esto significa que no habrá más restricciones en el subproceso principal, no más errores de E/S al usar Pyinstrument y no será necesario un modo separado más 'setprofile'!
Renderistas . Los usuarios pueden personalizar Pyinstrument para usar renderizadores alternativos con el argumento renderer
en Profiler.output()
o usando el argumento --renderer
en la línea de comando.
Grabadoras . Para admitir otros casos de uso de Pyinstrument (por ejemplo, gráficos de llamas), pyinstrument ahora tiene un modo de grabación de 'línea de tiempo'. Este modo registra los fotogramas capturados de forma lineal, por lo que la ejecución del programa se puede ver en una línea de tiempo.
pyinstrument
. Ahora puede generar perfiles de scripts de Python desde el shell ejecutando $ pyinstrument script.py
. Esto ahora es equivalente a python -m pyinstrument
. ¡Gracias @asmeurer!El código de la aplicación está resaltado en rastros HTML para que sea más fácil de detectar.
Se agregó la opción PYINSTRUMENT_PROFILE_DIR
a la interfaz de Django, que registrará los perfiles de todas las solicitudes en un archivo en la carpeta especificada. Útil para generar perfiles de llamadas API.
Se agregó la opción PYINSTRUMENT_USE_SIGNAL
a la interfaz de Django, para usar cuando el modo de señal presenta problemas.
Para configurar un entorno de desarrollo:
virtualenv --python=python3 env
. env/bin/activate
pip install --upgrade pip
pip install -r requirements-dev.txt
pre-commit install --install-hooks
Para obtener algunos resultados de muestra:
pyinstrument examples/wikipedia_article_word_count.py
Para ejecutar las pruebas:
pytest
Para ejecutar comprobaciones de pelusa localmente:
pre-commit run --all-files
Algunas de las comprobaciones previas a la confirmación, como isort
o black
, solucionarán automáticamente los problemas que encuentren. Entonces, si el comando anterior devuelve un error, intente ejecutarlo nuevamente, es posible que tenga éxito la segunda vez :)
Ejecutar todas las comprobaciones puede ser lento, por lo que también puede ejecutar comprobaciones individualmente, por ejemplo, para formatear el código fuente que falla en las comprobaciones isort
o black
:
pre-commit run --all-files isort
pre-commit run --all-files black
Para diagnosticar por qué fallan las comprobaciones pyright
:
pre-commit run --all-files pyright
El procesador HTML funciona incorporando una representación JSON de la muestra con un 'paquete' de Javascript dentro de un archivo HTML que se puede ver en cualquier navegador web.
Para editar el estilo de renderizado html, haga:
cd html_renderer
npm ci
npm run serve
Cuando se inicia sin un objeto window.profileSession
de nivel superior, obtendrá un perfil de muestra para que pueda trabajar con él.
Para compilar la aplicación JS y empaquetarla nuevamente en la herramienta Python pyinstrument:
bin/build_js_bundle.py [--force]