如何用Python的timeit测量代码段性能?
我有一个Python脚本,运行得很好,但我需要记录它的执行时间。我在网上查了,发现可以用timeit
这个工具,但我好像没法让它正常工作。
我的Python脚本长这样:
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
。这样做的目的是为了测试我的数据库更新语句,看看在不同的索引和调优机制下表现如何。
9 个回答
首先,这段代码有问题:你执行了100个连接(只关注最后一个),然后在第一次执行时,你传入了一个局部变量 query_stmt
,而这个变量是在执行调用之后才初始化的。
首先,先把代码修正过来,不用担心时间的问题:也就是说,写一个函数来建立连接,进行100次、500次或者其他次数的更新,然后关闭连接。等你的代码能正常工作后,再考虑用 timeit
来测试它的执行时间!
具体来说,如果你想要计时的函数是一个不带参数的函数,叫做 foobar
,你可以使用 timeit.timeit(2.6版本或更高,2.5及之前的版本会复杂一些):
timeit.timeit('foobar()', number=1000)
从3.5版本开始,globals
参数让你可以很方便地用 timeit
来测试带参数的函数:
timeit.timeit('foobar(x,y)', number=1000, globals = globals())
最好指定运行的次数,因为默认是一百万次,这对你的使用场景来说可能太多了(可能会花很多时间在这段代码上;-)。
如果你正在分析你的代码性能,并且可以使用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
你可以在想要测量时间的代码块前后使用 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
会在你设置它的 number 参数时自动处理这个)。
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.clock()
而不是 time.time()
。