这是一个简单程序的概要
# some pre-defined constants
A = 1
B = 2
# function that does something critical
def foo(num1, num2):
# do something
# main program.... do something to A and B
for i in range(20):
# do something to A and B
# and update A and B during each iteration
import timeit
t = timeit.Timer(stmt="foo(num1,num2)")
print t.timeit(5)
我只是不断得到“全球名称foo未定义”..... 谁可以帮我这个事?谢谢!
答案 0 :(得分:38)
如果这些函数是使用闭包创建的,那么函数可以使用timeit
中的参数,我们可以通过将它们包装在另一个函数中来添加这些行为。
def foo(num1, num2):
def _foo():
# do something to num1 and num2
pass
return _foo
A = 1
B = 2
import timeit
t = timeit.Timer(foo(A,B))
print t.timeit(5)
或更短,我们可以使用functools.partial而不是显式闭包声明
def foo(num1, num2):
# do something to num1 and num2
pass
A = 1
B = 2
import timeit, functools
t = timeit.Timer(functools.partial(foo, A, B))
print t.timeit(5)
答案 1 :(得分:14)
假设您的模块文件名是test.py
# some pre-defined constants
A = 1
B = 2
# function that does something critical
def foo(n, m):
pass
# main program.... do something to A and B
for i in range(20):
pass
import timeit
t = timeit.Timer(stmt="test.foo(test.A, test.B)", setup="import test")
print t.timeit(5)
答案 2 :(得分:13)
代码段必须是自包含的 - 它们不能进行外部引用。您必须在statement-string或setup-string中定义值:
import timeit
setup = """
A = 1
B = 2
def foo(num1, num2):
pass
def mainprog():
global A,B
for i in range(20):
# do something to A and B
foo(A, B)
"""
t = timeit.Timer(stmt="mainprog()" setup=setup)
print(t.timeit(5))
更好的是,重写代码以不使用全局值。
答案 3 :(得分:9)
您的功能需要在设置字符串中定义。执行此操作的一种好方法是在模块中设置代码,这样您就可以轻松完成
t = timeit.Timer("foo(num1, num2)", "from myfile import foo")
t.timeit(5)
否则,您必须在setup语句中将所有设置定义为字符串。
setup = """
# some pre-defined constants
A = 1
B = 2
# function that does something critical
def foo(num1, num2):
# do something
# main program.... do something to A and B
for i in range(20):
# do something to A and B
# and update A and B during each iteration
"""
t = timeit.Timer("foo(num1, num2)", setup)
t.timeit(5)
我刚刚发现的令人敬畏的是使用cProfile的iPython的快捷方式。
def foo(x, y):
print x*y
%prun foo("foo", 100)
答案 4 :(得分:8)
我通常会创建一个额外的功能:
def f(x,y):
return x*y
v1 = 10
v2 = 20
def f_test():
f(v1,v2)
print(timeit.timeit("f_test()", setup="from __main__ import f_test"))
答案 5 :(得分:2)
以下是如何在不调用全局变量的情况下划分定时例程的示例
def foo(a, b):
'''Do something to `a` and `b`'''
return a + b
def time_foo():
'''Create timer object simply without using global variables'''
import timeit
_foo = foo
a = 1
b = 2
# Get `Timer` oject, alternatively just get time with `timeit.timeit()`
t = timeit.Timer('_foo(a, b)', globals=locals())
return t
如果你想使用相同的timeit
函数计时其他函数,你甚至可以概括这一点。以下是您的示例main()
例程的示例:
def foo1(a, b):
'''Add `a` and `b`'''
return a + b
def foo2(a, b):
'''More math on `a` and `b`'''
return (a**2 * b)**2
def time_foo(func, **kwargs):
'''Create timer object simply without using global variables'''
import timeit
return timeit.timeit('func(**kwargs)', globals=locals())
def run():
'''Modify inputs to foo and see affect on execution time'''
a = 1
b = 2
for i in range(10):
# Update `a` and `b`
a += 1
b += 2
# Pass args to foo as **kwargs dict
print('foo1 time: ', time_foo(foo1, **{'a':a, 'b':b}))
print('foo2 time: ', time_foo(foo2, **{'a':a, 'b':b}))
return None
答案 6 :(得分:2)
有一个更简单的解决方案(至少对于Python 3是这样),您可以使代码在当前的全局命名空间中执行:
t = timeit.Timer(stmt="foo(num1,num2)", globals=globals())
https://docs.python.org/3/library/timeit.html#examples 我知道全局变量不是首选,但是如果您只是编写一个快速脚本来检查某些内容,我认为这是最简单的实现。
答案 7 :(得分:0)
我更喜欢创建一个static
类,其中所有数据都准备好在运行计时器之前被拾取。
另一方面,由于全球空间没有利用
,因此最好在功能中而不是在全球空间中进行测试运行。FAST_LOAD
Why does Python code run faster in a function?
class Data(object):
"""Data Creation"""
x = [i for i in range(0, 10000)]
y = tuple([i for i in range(0, 10000)])
def __init__(self):
pass
import timeit
def testIterator(x):
for i in range(10000):
z = i
print timeit.timeit("testIterator(Data.x)", setup="from __main__ import testIterator, Data", number=50)
print timeit.timeit("testIterator(Data.y)", setup="from __main__ import testIterator, Data", number=50)
答案 8 :(得分:0)
这应该有效:
import timeit
def f(x,y):
return x*y
x = 5
y = 7
print(timeit.timeit(stmt='f(x,y)',
setup='from __main__ import f, x, y',
number=1000))
答案 9 :(得分:0)
我今天正在使用Python 3.7进行计时,并试图将函数和变量传递给计时器。这就是我想出的。
import re
text = "This is a test of the emergency broadcast system"
def regex(text):
return re.sub(r"(\s)\1{1,}", r"\1", text)
def loop_while(text):
if " " in text:
while " " in text:
text = text.replace(" ", " ")
return text
if __name__ == "__main__":
import timeit
callable_functions = [item for item in locals().items() if callable(item[1])]
for func_name, func in callable_functions:
elapsed_time = timeit.timeit(f"{func_name}(text)", globals=globals(), number=100000)
print(f"{func_name}: {elapsed_time} \n{func(text)}\n")
这将输出:
regex:1.378352418
这是对紧急广播系统的测试loop_while:0.15858950299999997
这是对紧急情况的考验 广播系统
然后,测试新版本所需要做的就是添加新功能。像这样:
def split_join(text):
return " ".join(text.split())
现在它输出:
regex:1.378352418
这是对紧急广播系统的测试loop_while:0.15858950299999997
这是对紧急广播系统的测试split_join:0.05700970800000005
这是对紧急广播系统的测试
答案 10 :(得分:0)
def findMax(n):#n is an array
m = 0
c = 0
for i in range(len(n)):
c += 1
if m < n[i]:
m = n[i]
return m, c
import timeit
import functools
a = [6, 2, 9, 3, 7, 4, 5]
t = timeit.Timer(functools.partial(findMax,a))
t.timeit(100)
答案 11 :(得分:0)
您必须在设置字符串中创建变量。在这里,我导入函数,并创建传递给它的变量之一。我还通过将变量之一强制转换为stmt字符串来设置
SETUP = '''
from __main__ import policy_iteration
from environments.gridworld import GridworldEnv
env = GridworldEnv()
'''
discount = 5
timeit.timeit("policy_iteration(env,discount_factor="+str(discount)+")",
setup= SETUP,
number=10))