Documentação
Pyinstrument é um criador de perfil Python. Um criador de perfil é uma ferramenta para ajudá-lo a otimizar seu código – torná-lo mais rápido. Para obter o maior aumento de velocidade, você deve se concentrar na parte mais lenta do seu programa. Pyinstrument ajuda você a encontrá-lo!
☕️ Não sabe por onde começar? Confira este tutorial em vídeo do calmcode.io!
pip install pyinstrument
Pyinstrument suporta Python 3.8+.
Para executar o Pyinstrument a partir de um checkout do git, há uma etapa de construção. Dê uma olhada em Contribuindo para mais informações.
Para aprender como usar o pyinstrument, ou para verificar a referência, acesse a documentação.
pyinstrument script.py
onde script.py
contém uma classe serializada com pickle
, você pode encontrar erros porque o mecanismo de serialização não sabe onde __main__
está. Consulte este problema para soluções alternativas 11 de outubro de 2024
Muitas melhorias no renderizador HTML!
Modo linha do tempo - veja e amplie uma linha do tempo linear interativa!
O modo HTML agora tem opções interativas, em vez de precisar definir antecipadamente.
Simplificou o design do cabeçalho da página HTML.
A visualização da pilha de chamadas HTML oferece suporte à navegação com teclas de seta.
A forma como o código da 'biblioteca' é detectado foi alterada. Anteriormente, se a string '/lib/' ocorresse no caminho do arquivo, isso era considerado código de biblioteca (e recolhido por padrão). Agora, o pyinstrument captura os caminhos da instalação do Python e qualquer ambiente virtualenv/conda ativo no momento do perfil. Os arquivos armazenados lá são considerados biblioteca. Isso deve dar menos falsos positivos.
Chamadas para profiler.start() agora podem passar um parâmetro target_description, que é exibido na leitura do perfil.
Verifique minha postagem no blog para obter mais informações sobre os novos recursos.
6 de setembro de 2024
glom
no Python 3.12 ou posterior, o que altera o ditado locals(). (#336)UnicodeDecodeError
em algumas plataformas (#330)5 de agosto de 2024
2 de agosto de 2024
1º de agosto de 2024
with
ou um decorador de função/método. Isso criará o perfil do código e imprimirá uma breve leitura no terminal. (#327)flat
à saída do console, para apresentar uma lista simples de funções (#294)26 de janeiro de 2024
show_all
ao Profiler.output_html8 de novembro de 2023
%pyinstrument
(#278)12 de outubro de 2023
-c
, que permite criar perfil de código diretamente da linha de comando, como python -c
. (#271)Profiler.write_html
, para gravar a saída HTML diretamente em um arquivo. (#266)7 de setembro de 2023
1º de setembro de 2023
22 de julho de 2023
[X frames hidden]
na saída quando os quadros eram excluídos devido a __tracebackhide__
(#255)None
na saída do console (#254)5 de junho de 2023
-p flat
na linha de comando. Este modo mostra o quadro mais pesado medido pelo tempo próprio, o que pode ser útil em algumas bases de código. (#240)pstats
. Este é o formato de arquivo usado pelo cprofile no stdlib. É menos detalhado que os perfis pyinstrument, mas é compatível com mais ferramentas. (#236)--show-all
- o pyinstrument não removerá mais frames internos do Python quando esta opção for fornecida. (#239)5 de novembro de 2022
__traceback_hide__
agora serão removidos da saída (#217)--async_mode=enabled
. (#212)21 de agosto de 2022
--interval
(segundos, padrão 0,001) para alterar o intervalo em que o pyinstrument faz a amostragem de um programa. Isto é útil para programas de longa execução, onde aumentar o intervalo reduz a sobrecarga de memória. Adiciona uma opção de linha de comando -p
--render-option
que permite configuração arbitrária de opções de renderização. Isso permite definir opções como filter_threshold
na linha de comando, fazendo algo como pyinstrument -p processor_options.filter_threshold=0
.
Aqui está a saída de ajuda para a opção:
-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.
Adiciona a capacidade de visualizar tempos na saída do console como porcentagens, em vez de tempos absolutos. Use a opção ConsoleRenderer time='percent_of_total'
ou na linha de comando, use -p
, como pyinstrument -p time=percent_of_total
.
Adiciona opções de linha de comando para carregar e salvar sessões do pyinstrument. Você pode salvar os dados brutos para uma sessão pyinstrument com -r session
, como pyinstrument -r session -o session.pyisession myscript.py
. O carregamento é via --load
, por exemplo, pyinstrument --load session.pyisession
.
O formato de saída da linha de comando é inferido da extensão do arquivo de saída -o
. Portanto, se você fizer pyinstrument -o profile.html myscript.py
, não precisará fornecer -r html
, pyinstrument usará automaticamente o renderizador HTML. Ou se você fizer pyinstrument -o profile.pyisession myscript.py
, ele salvará um objeto de sessão bruto.
Adiciona exemplos de uso de FastAPI e pytest à documentação.
Corrige um bug que causava NotImplementedError ao usar async_mode=strict
.
Adiciona suporte para Python 3.11
%load_ext pyinstrument
na parte superior do seu notebook e, em seguida, %%pyinstrument
na célula cujo perfil deseja criar.pyinstrument -r speedscope
e faça upload para o aplicativo da web speedscope.PYINSTRUMENT_PROFILE_DIR_RENDERER
.Suporte assíncrono! O Pyinstrument agora detecta quando uma tarefa assíncrona atinge uma espera e rastreia o tempo gasto fora do contexto assíncrono sob essa espera.
Então, por exemplo, aqui está um script simples com uma tarefa assíncrona que dorme:
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 do Pyinstrument 4.0.0, veríamos apenas o tempo gasto no loop de execução, assim:
_ ._ __/__ _ _ _ _ _/_ 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
Agora, com o pyinstrument 4.0.0, obtemos:
_ ._ __/__ _ _ _ _ _/_ 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 obter mais informações, confira a documentação de criação de perfil assíncrono e a propriedade Profiler.async_mode.
Pyinstrument tem um site de documentação, incluindo documentos completos da API Python!
--show
, --show-regex
, --show-all
fossem ignorados na linha de comando.timeline
(booleana) aos métodos do Profiler output_html()
e open_in_browser()
.pyinstrument -m module
, onde pyinstrument não encontrava módulos no diretório atual.Python -> C -> Python
é registrado como Python -> Python
, mas Python -> Python -> C
será atribuído corretamente. (#103)<__array_function__ internals>
que aparecem como código de aplicativo em relatórios--show
e --show-regex
, para marcar determinados arquivos a serem exibidos. Isso ajuda a criar perfis dentro de módulos específicos, enquanto oculta outros. Por exemplo, pyinstrument --show '*/sympy/*' script.py
.O Pyinstrument agora ocultará rastros por meio de bibliotecas que você usa por padrão. Então, em vez de mostrar muitos frames passando pelas partes internas de algo externo, por exemplo, urllib, ele permite que você se concentre em seu código.
Antes | Depois |
---|---|
Para voltar ao comportamento antigo, use --show-all
na linha de comando.
Quadros de 'entrada' de grupos ocultos são mostrados, para que você saiba qual chamada é o problema
Os quadros realmente lentos nos grupos também são mostrados, por exemplo, a chamada 'read' no soquete
O código do aplicativo é destacado no console
Métricas adicionais são mostradas na parte superior do rastreamento: carimbo de data/hora, número de amostras, duração, tempo de CPU
O código oculto é controlado pelas opções --hide
ou --hide-regex
- correspondentes ao caminho dos arquivos 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.
A saída de uma linha do tempo é suportada na linha de comando.
-t, --timeline render as a timeline - preserve ordering and don't
condense repeated calls
Como existem algumas opções de renderização agora, você pode carregar uma sessão de criação de perfil anterior usando --load-prev
- o pyinstrument mantém as últimas 10 sessões.
Grupos ocultos também podem retornar ao código do aplicativo, semelhante a este:
(interno) Ao gravar linhas de tempo, as árvores de quadros agora são completamente lineares, permitindo a criação de gráficos de quadros superprecisos.
(interno) O renderizador HTML foi reescrito como um aplicativo Vue.js. Todas as melhorias do console também se aplicam à saída HTML, além de ser interativa.
(interno) Muitos testes unitários e de integração adicionados!
Caramba! Consulte o nº 49 para obter os detalhes sangrentos. Espero que você goste.
Recorders
foram removidos. A gravação do quadro agora é interna ao objeto Profiler
. Isso significa que os objetos 'frame' são de uso mais geral, o que abre caminho para...--version
Adicionado suporte para saída JSON. Use pyinstrument --renderer=json scriptfile.py
. RP
@iddan montou um visualizador interativo usando a saída JSON!
Ao executar pyinstrument --html
e você não canalizar a saída para um arquivo, o pyinstrument gravará a saída do console em um arquivo temporário e o abrirá em um navegador.
-m
, por exemplo, pyinstrument -m module_name
! RP Pyinstrument agora pode ser usado em um bloco with
.
Por exemplo:
profiler = pyinstrument.Profiler()
with profiler:
# do some work here...
print(profiler.output_text())
Correção de middleware para versões mais antigas do Django
Pyinstrument usa um novo modo de criação de perfil . Em vez de usar sinais, o pyintrument usa um novo perfil estatístico construído em PyEval_SetProfile. Isso significa que não há mais restrições de thread principal, não há mais erros de IO ao usar o Pyinstrument e não há necessidade de um modo separado mais 'setprofile'!
Renderizadores . Os usuários podem personalizar o Pyinstrument para usar renderizadores alternativos com o argumento renderer
em Profiler.output()
ou usando o argumento --renderer
na linha de comando.
Gravadores . Para oferecer suporte a outros casos de uso do Pyinstrument (por exemplo, gráficos em chamas), o pyinstrument agora possui um modo de gravador de 'linha do tempo'. Este modo registra os quadros capturados de forma linear, para que a execução do programa possa ser visualizada em uma linha do tempo.
pyinstrument
. Agora você pode criar o perfil de scripts python a partir do shell executando $ pyinstrument script.py
. Agora isso é equivalente a python -m pyinstrument
. Obrigado @asmeurer!O código do aplicativo é destacado em traços HTML para facilitar a localização
Adicionada a opção PYINSTRUMENT_PROFILE_DIR
à interface do Django, que registrará perfis de todas as solicitações em um arquivo na pasta especificada. Útil para criar perfis de chamadas de API.
Adicionada opção PYINSTRUMENT_USE_SIGNAL
à interface do Django, para uso quando o modo sinal apresentar problemas.
Para configurar um ambiente de desenvolvimento:
virtualenv --python=python3 env
. env/bin/activate
pip install --upgrade pip
pip install -r requirements-dev.txt
pre-commit install --install-hooks
Para obter um exemplo de saída:
pyinstrument examples/wikipedia_article_word_count.py
Para executar os testes:
pytest
Para executar verificações de linting localmente:
pre-commit run --all-files
Algumas das verificações pré-confirmação, como isort
ou black
, corrigirão automaticamente os problemas encontrados. Portanto, se o comando acima retornar um erro, tente executá-lo novamente, ele poderá funcionar na segunda vez :)
A execução de todas as verificações pode ser lenta, então você também pode executar verificações individualmente, por exemplo, para formatar o código-fonte que falha nas verificações isort
ou black
:
pre-commit run --all-files isort
pre-commit run --all-files black
Para diagnosticar por que as verificações pyright
estão falhando:
pre-commit run --all-files pyright
O renderizador HTML funciona incorporando uma representação JSON da amostra com um 'pacote' Javascript dentro de um arquivo HTML que pode ser visualizado em qualquer navegador da web.
Para editar o estilo do renderizador HTML, faça:
cd html_renderer
npm ci
npm run serve
Quando iniciado sem um objeto window.profileSession
de nível superior, ele buscará um perfil de amostra para que você possa trabalhar com ele.
Para compilar o aplicativo JS e agrupá-lo de volta na ferramenta python pyinstrument:
bin/build_js_bundle.py [--force]