How can I time a code segment for testing performance with Pythons timeit?
我有一个可以正常工作的Python脚本,但我需要编写执行时间。我在google上搜索到我应该使用
我的python脚本如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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 " % r ibm_db.execute(query_stmt) query_stmt = ibm_db.prepare(conn, update) myfile.close() ibm_db.close(conn) |
我需要的是执行查询并将其写入文件
您可以在要计时的块之前和之后使用
1 2 3 4 5 6 7 | import time t0 = time.time() code_block t1 = time.time() total = t1-t0 |
这种方法不如
1 2 3 4 5 6 7 8 9 10 11 | 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在评论中所说,
如果您正在分析代码并可以使用ipython,那么它具有魔力函数
1 2 3 4 5 6 7 8 | 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 |
除了时间之外,您所显示的代码是完全不正确的:您执行100个连接(完全忽略最后一个连接以外的所有连接),然后当您执行第一个执行调用时,将传递给它一个局部变量
首先,让您的代码正确无误,而不必担心时间问题:即,一个建立或接收连接并在该连接上执行100或500或任何数量的更新的函数,然后关闭该连接。一旦您的代码工作正常,您就可以正确地考虑在上面使用
具体来说,如果要计时的函数是一个参数,而不是一个名为
1 | timeit.timeit('foobar()', number=1000) |
您最好指定运行次数,因为对于您的用例,默认值一百万可能很高(这会导致在代码中花费大量时间;-)。
专注于一件具体的事情。磁盘I/O速度很慢,所以如果您要调整的只是数据库查询,那么我将把它从测试中去掉。
如果您需要对数据库的执行进行计时,那么可以寻找数据库工具,比如询问查询计划,并注意性能不仅会随着准确的查询和所拥有的索引而变化,还会随着数据负载(存储了多少数据)而变化。
也就是说,您只需将代码放入一个函数中,并使用
1 2 3 4 | def function_to_repeat(): # ... duration = timeit.timeit(function_to_repeat, number=1000) |
这将禁用垃圾收集,重复调用
您应该将设置代码移出重复的函数;例如,您应该首先连接到数据库,然后只对查询计时。使用
1 2 3 4 5 6 7 | def function_to_repeat(var1, var2): # ... duration = timeit.timeit( 'function_to_repeat(var1, var2)', 'from __main__ import function_to_repeat, var1, var2', number=1000) |
将从脚本中获取全局的
我看到问题已经被回答了,但还是想加上我的2分。
我也遇到过类似的情况,在这种情况下,我必须测试几种方法的执行时间,然后编写一个小脚本,在其中编写的所有函数上调用timeit。
该脚本也可以在这里作为Github Gist使用。
希望它能帮助你和其他人。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 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();" 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") |