我有一个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所需的时间。目的是用不同的索引和调优机制测试数据库的更新语句。


当前回答

专注于一件具体的事情。磁盘I/O很慢,所以如果您要调整的只是数据库查询,我就把它从测试中去掉。

如果您需要计算数据库执行的时间,请寻找数据库工具,例如询问查询计划,并注意性能不仅随确切的查询和您拥有的索引而变化,还随数据负载(您存储了多少数据)而变化。

也就是说,你可以简单地把你的代码放在一个函数中,并使用time .timeit()运行该函数:

def function_to_repeat():
    # ...

duration = timeit.timeit(function_to_repeat, number=1000)

这将禁用垃圾收集,重复调用function_to_repeat()函数,并使用timeit.default_timer()计算这些调用的总持续时间,这是特定平台可用的最准确的时钟。

你应该把设置代码移出重复函数;例如,您应该首先连接到数据库,然后仅计时查询。使用setup参数导入或创建这些依赖项,并将它们传递到你的函数中:

def function_to_repeat(var1, var2):
    # ...

duration = timeit.timeit(
    'function_to_repeat(var1, var2)',
    'from __main__ import function_to_repeat, var1, var2', 
    number=1000)

将从脚本中抓取全局函数to_repeat, var1和var2,并将它们每次重复传递给函数。

其他回答

如何使用timeit为函数计时:

import timeit

def time_this():
    return 'a' + 'b'

timeit.timeit(time_this, number=1000)

它返回运行time_this() 1000次所花费的时间(以秒为单位)。

如果您正在分析代码,并且可以使用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

撇开时间不提,您所显示的代码完全不正确:执行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())

您最好指定运行次数,因为对于您的用例来说,默认的100万可能太高了(导致在这段代码中花费大量时间;-)。

另一个简单的timeit例子:

def your_function_to_test():
   # do some stuff...

time_to_run_100_times = timeit.timeit(lambda: your_function_to_test, number=100)

专注于一件具体的事情。磁盘I/O很慢,所以如果您要调整的只是数据库查询,我就把它从测试中去掉。

如果您需要计算数据库执行的时间,请寻找数据库工具,例如询问查询计划,并注意性能不仅随确切的查询和您拥有的索引而变化,还随数据负载(您存储了多少数据)而变化。

也就是说,你可以简单地把你的代码放在一个函数中,并使用time .timeit()运行该函数:

def function_to_repeat():
    # ...

duration = timeit.timeit(function_to_repeat, number=1000)

这将禁用垃圾收集,重复调用function_to_repeat()函数,并使用timeit.default_timer()计算这些调用的总持续时间,这是特定平台可用的最准确的时钟。

你应该把设置代码移出重复函数;例如,您应该首先连接到数据库,然后仅计时查询。使用setup参数导入或创建这些依赖项,并将它们传递到你的函数中:

def function_to_repeat(var1, var2):
    # ...

duration = timeit.timeit(
    'function_to_repeat(var1, var2)',
    'from __main__ import function_to_repeat, var1, var2', 
    number=1000)

将从脚本中抓取全局函数to_repeat, var1和var2,并将它们每次重复传递给函数。