Pythons timeit로 성능을 테스트하기 위해 코드 세그먼트의 시간을 어떻게 정할 수 있습니까?
파이썬 스크립트는 정상적으로 작동하지만 실행 시간을 써야합니다. 사용해야한다고 Google에서 확인 timeit
했지만 작동하지 않는 것 같습니다.
내 파이썬 스크립트는 다음과 같습니다
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)
내가 필요한 것은 쿼리를 실행하고 파일에 쓰는 데 걸리는 시간 results_update.txt
입니다. 목적은 다른 인덱스 및 조정 메커니즘으로 데이터베이스에 대한 업데이트 명령문을 테스트하는 것입니다.
당신은 사용할 수 있습니다 time.time()
또는 time.clock()
전에 당신이 시간에 원하는 블록 후.
import time
t0 = time.time()
code_block
t1 = time.time()
total = t1-t0
이 방법은 정확 timeit
하지는 않지만 (몇 번의 런을 평균하지는 않음) 간단합니다.
time.time()
(Windows 및 Linux) 및 time.clock()
(Linux)는 빠른 기능을 위해 충분히 정확하지 않습니다 (총 = 0을 얻음). 이 경우 또는 여러 번의 실행으로 경과 된 시간을 평균하려면 함수를 여러 번 수동으로 호출해야합니다 (이미 예제에서 수행 한 것처럼 숫자 인수 를 설정하면 timeit가 자동으로 수행됩니다 )
import time
def myfast():
code
n = 10000
t0 = time.time()
for i in range(n): myfast()
t1 = time.time()
total_n = t1-t0
Windows에서 Corey는 의견에서 언급했듯이 time.clock()
훨씬 높은 정밀도 (초 대신 마이크로 초)를 가지며보다 선호됩니다 time.time()
.
코드를 프로파일 링하고 IPython을 사용할 수있는 경우 매직 기능이 %timeit
있습니다.
%%timeit
세포에서 작동합니다.
In [2]: %timeit cos(3.14)
10000000 loops, best of 3: 160 ns per loop
In [3]: %%timeit
...: cos(3.14)
...: x = 2 + 3
...:
10000000 loops, best of 3: 196 ns per loop
Quite apart from the timing, this code you show is simply incorrect: you execute 100 connections (completely ignoring all but the last one), and then when you do the first execute call you pass it a local variable query_stmt
which you only initialize after the execute call.
First, make your code correct, without worrying about timing yet: i.e. a function that makes or receives a connection and performs 100 or 500 or whatever number of updates on that connection, then closes the connection. Once you have your code working correctly is the correct point at which to think about using timeit
on it!
Specifically, if the function you want to time is a parameter-less one called foobar
you can use timeit.timeit (2.6 or later -- it's more complicated in 2.5 and before):
timeit.timeit('foobar()', number=1000)
You'd better specify the number of runs because the default, a million, may be high for your use case (leading to spending a lot of time in this code;-).
Focus on one specific thing. Disk I/O is slow, so I'd take that out of the test if all you are going to tweak is the database query.
And if you need to time your database execution, look for database tools instead, like asking for the query plan, and note that performance varies not only with the exact query and what indexes you have, but also with the data load (how much data you have stored).
That said, you can simply put your code in a function and run that function with timeit.timeit()
:
def function_to_repeat():
# ...
duration = timeit.timeit(function_to_repeat, number=1000)
This would disable the garbage collection, repeatedly call the function_to_repeat()
function, and time the total duration of those calls using timeit.default_timer()
, which is the most accurate available clock for your specific platform.
You should move setup code out of the repeated function; for example, you should connect to the database first, then time only the queries. Use the setup
argument to either import or create those dependencies, and pass them into your function:
def function_to_repeat(var1, var2):
# ...
duration = timeit.timeit(
'function_to_repeat(var1, var2)',
'from __main__ import function_to_repeat, var1, var2',
number=1000)
would grab the globals function_to_repeat
, var1
and var2
from your script and pass those to the function each repetition.
I see the question has already been answered, but still want to add my 2 cents for the same.
I have also faced similar scenario in which I have to test the execution times for several approaches and hence written a small script, which calls timeit on all functions written in it.
The script is also available as github gist here.
Hope it will help you and others.
from random import random
import types
def list_without_comprehension():
l = []
for i in xrange(1000):
l.append(int(random()*100 % 100))
return l
def list_with_comprehension():
# 1K random numbers between 0 to 100
l = [int(random()*100 % 100) for _ in xrange(1000)]
return l
# operations on list_without_comprehension
def sort_list_without_comprehension():
list_without_comprehension().sort()
def reverse_sort_list_without_comprehension():
list_without_comprehension().sort(reverse=True)
def sorted_list_without_comprehension():
sorted(list_without_comprehension())
# operations on list_with_comprehension
def sort_list_with_comprehension():
list_with_comprehension().sort()
def reverse_sort_list_with_comprehension():
list_with_comprehension().sort(reverse=True)
def sorted_list_with_comprehension():
sorted(list_with_comprehension())
def main():
objs = globals()
funcs = []
f = open("timeit_demo.sh", "w+")
for objname in objs:
if objname != 'main' and type(objs[objname]) == types.FunctionType:
funcs.append(objname)
funcs.sort()
for func in funcs:
f.write('''echo "Timing: %(funcname)s"
python -m timeit "import timeit_demo; timeit_demo.%(funcname)s();"\n\n
echo "------------------------------------------------------------"
''' % dict(
funcname = func,
)
)
f.close()
if __name__ == "__main__":
main()
from os import system
#Works only for *nix platforms
system("/bin/bash timeit_demo.sh")
#un-comment below for windows
#system("cmd timeit_demo.sh")
Here's a simple wrapper for steven's answer. This function doesn't do repeated runs/averaging, just saves you from having to repeat the timing code everywhere :)
'''function which prints the wall time it takes to execute the given command'''
def time_func(func, *args): #*args can take 0 or more
import time
start_time = time.time()
func(*args)
end_time = time.time()
print("it took this long to run: {}".format(end_time-start_time))
'Programing' 카테고리의 다른 글
"|"는 무엇을 하는가 (0) | 2020.06.23 |
---|---|
SQL varchar에서 특정 하위 문자열의 발생 횟수를 어떻게 계산합니까? (0) | 2020.06.23 |
DateTimePicker : 날짜와 시간을 모두 선택 (0) | 2020.06.23 |
iOS 5.1 SDK의 iPad 시뮬레이터에 "홈"버튼이없는 이유는 무엇입니까? (0) | 2020.06.23 |
HttpClient를 사용하여 Https 호출 (0) | 2020.06.23 |