我最近注意到关于timeit
python模块的以下内容:
在我的机器上行:
from timeit import Timer
t = Timer(stmt='a = 2**3**4')
print("This took {:.3f}s to execute.".format(t.timeit()))
将产生:
这需要0.017秒才能执行。
另一方面,写一个文件 test.py :
#!/usr/bin/env python3
a = 2**3**4
并致电:
from timeit import Timer
t = Timer(stmt='import test')
print("This took {:.3f}s to execute.".format(t.timeit()))
将产生:
这需要0.126秒来执行。
我想知道如何在不更改文件本身的情况下测试test.py
的执行时间。我如何处理导入文件(因此失去时间)。
答案 0 :(得分:2)
您的测量存在一个问题:当您写作时,您没有测量您认为测量的内容:
t = Timer(stmt= 'a = 2**3**4')
您正在测量绑定时间!看:
>>> Timer(stmt='a = 10**5**4').timeit(100000)
0.0064544077574026915
>>> Timer(stmt='a = 2**3**4').timeit(100000)
0.006511381058487586
计时相同,但计算10**5**4
的时间比2**3**4
长一些。编译代码时,2**3**4
只计算一次,这称为“常量折叠”,这是Python在编译源代码时执行的一些优化。
比较这两个结果:
>>> Timer(stmt= 'a = 2**3**4').timeit(100000)
0.00628656749199763
>>> Timer(stmt= 'a = x**y**z', setup='(x,y,z)=(2,3,4)').timeit(100000)
0.18055968312580717
但这种加速不是免费提供的。有两点:
.pyc
文件大小增加(因为此值存储在.pyc
文件中)假设我有两个文件:
#foo1.py
a = 10**7**7
#foo2.py
x,y,z =(10,7,7)
a = x**y**z
如果我用python -m py_compile foo1.py foo2.py
编译它们,我机器上.pyc
个文件的大小将为:
foo1.cpython-36.pyc
- 364 882 bytes foo2.cpython-36.pyc
- 150个字节答案 1 :(得分:1)
您最接近的是compile
与exec
一起使用如果您打算作为.pyc文件运行,请不要在您的计时中包含编译语句。
# time as if executing:" >python test.pyc " from terminal
# (importing test.py will typically automatically generate the .pyc file automatically)
t = Timer(stmt='exec(code_object)',
setup='code_object = compile(open("test.py").read(), "test.py", "exec")')
# time as if executing:" >python test.py " from terminal
t = Timer(stmt='exec(compile(open("test.py").read(), "test.py", "exec"))')
这可以让您接近从终端调用脚本的实际时间。这并不能消除开销,因为调用脚本的开销是真实的,并且会在现实世界中被观察到。
如果你使用的是基于Linux的系统,你也可以从终端呼叫>time test.py
。