Eu tenho um script python que funciona exatamente como deveria, mas preciso escrever o tempo de execução. Pesquisei no Google que deveria usar, timeit
mas não consigo fazê-lo funcionar.
Meu script Python fica assim:
import sys
import getopt
import timeit
import random
import os
import re
import ibm_db
import time
from string import maketrans
myfile = open("results_update.txt", "a")
for r in range(100):
rannumber = random.randint(0, 100)
update = "update TABLE set val = %i where MyCount >= '2010' and MyCount < '2012' and number = '250'" % rannumber
#print rannumber
conn = ibm_db.pconnect("dsn=myDB","usrname","secretPWD")
for r in range(5):
print "Run %s\n" % r
ibm_db.execute(query_stmt)
query_stmt = ibm_db.prepare(conn, update)
myfile.close()
ibm_db.close(conn)
O que eu preciso é o tempo que leva para executar a consulta e gravá-la no arquivo results_update.txt
. O objetivo é testar uma instrução de atualização para meu banco de dados com diferentes índices e mecanismos de ajuste.
python
testing
timeit
database-tuning
Mestika
fonte
fonte
timeit
? Eu acho que não. Nesse caso, você provavelmente deve remover "with Pythons timeit" do título.Respostas:
Você pode usar
time.time()
outime.clock()
antes e depois do bloco que deseja cronometrar.Esse método não é tão exato quanto
timeit
(não mede várias execuções), mas é direto.time.time()
(no Windows e Linux) etime.clock()
(no Linux) não são precisos o suficiente para funções rápidas (você obtém total = 0). Nesse caso, ou se você deseja calcular a média do tempo decorrido por várias execuções, é necessário chamar manualmente a função várias vezes (como eu acho que você já faz no exemplo de código e tempo, isso acontece automaticamente quando você define seu argumento numérico )No Windows, como Corey afirmou no comentário,
time.clock()
tem uma precisão muito maior (microssegundo em vez de segundo) e é preferíveltime.time()
.fonte
timeit.default_timer
; O Python já fez o trabalho para você. Mas, na verdade, você deve usar emtimeit.timeit(myfast, number=n)
vez de reinventar a roda de chamada repetitiva (e perder o fato de quetimeit
desativa o coletor de lixo enquanto executa o código repetidamente).Se você cria um perfil do seu código e pode usar o IPython, ele tem a função mágica
%timeit
.%%timeit
opera em células.fonte
Independentemente do tempo, esse código que você mostra é simplesmente incorreto: você executa 100 conexões (ignorando completamente todas, exceto a última) e, em seguida, quando você faz a primeira chamada de execução, passa uma variável local
query_stmt
que somente inicializa após a execução ligar.Primeiro, corrija seu código, sem se preocupar com o tempo ainda: ou seja, uma função que faz ou recebe uma conexão e executa 100 ou 500 ou qualquer número de atualizações nessa conexão e, em seguida, fecha a conexão. Depois de ter seu código funcionando corretamente, é o ponto correto para pensar em usá
timeit
-lo!Especificamente, se a função que você deseja cronometrar for uma chamada sem parâmetro,
foobar
você pode usar timeit.timeit (2.6 ou posterior - é mais complicado no 2.5 e anterior):É melhor especificar o número de execuções, porque o padrão, um milhão, pode ser alto para o seu caso de uso (levando a gastar muito tempo nesse código ;-).
fonte
foobar
estiver em um arquivo principal. Assim:timeit.timeit('foobar()','from __main__ import foobar',number=1000)
timeit.timeit( foobar, number=1000 )
Concentre-se em uma coisa específica . A E / S do disco é lenta, portanto, eu a retiraria do teste se tudo o que você quiser ajustar é a consulta ao banco de dados.
E se você precisar cronometrar a execução do banco de dados, procure por ferramentas de banco de dados, como solicitar o plano de consulta e observe que o desempenho varia não apenas com a consulta exata e quais índices você possui, mas também com a carga de dados (quantos dados você armazenou).
Dito isso, você pode simplesmente colocar seu código em uma função e executá-la com
timeit.timeit()
:Isso desabilitaria a coleta de lixo, chamava repetidamente a
function_to_repeat()
função e cronometra a duração total dessas chamadas usandotimeit.default_timer()
, que é o relógio disponível mais preciso para sua plataforma específica.Você deve mover o código de configuração para fora da função repetida; por exemplo, você deve se conectar ao banco de dados primeiro e depois cronometrar apenas as consultas. Use o
setup
argumento para importar ou criar essas dependências e passá-las para sua função:iria pegar os globals
function_to_repeat
,var1
evar2
de seu roteiro e passar aqueles com a função de cada repetição.fonte
eval
ing não voará por algo não completamente trivial. thxVejo que a pergunta já foi respondida, mas ainda quero adicionar meus 2 centavos pelo mesmo.
Também enfrentei um cenário semelhante no qual tenho que testar os tempos de execução para várias abordagens e, portanto, escrevi um pequeno script, que chama timeit em todas as funções nele escritas.
O script também está disponível como github gist aqui .
Espero que ajude você e outras pessoas.
fonte
Aqui está um invólucro simples para a resposta de steven. Esta função não faz repetidas execuções / média, apenas evita que você precise repetir o código de temporização em todos os lugares :)
fonte
O conjunto de testes não tenta usar o importado,
timeit
por isso é difícil dizer qual era a intenção. No entanto, esta é uma resposta canônica, portanto um exemplo completo detimeit
parece em ordem, elaborando a resposta de Martijn .Os documentos para
timeit
oferecem muitos exemplos e sinalizadores que valem a pena conferir. O uso básico na linha de comando é:Corra com
-h
para ver todas as opções. O MOTW do Python tem uma ótima seçãotimeit
que mostra como executar módulos através de cadeias de código de importação e multilinhas na linha de comando.Em forma de script, eu normalmente uso assim:
Você pode facilmente inserir as funções e argumentos necessários. Tenha cuidado ao usar funções impuras e cuide do estado.
Saída de amostra:
fonte
Outro exemplo simples de timeit:
fonte