Python - 克服timeit中的导入

时间:2017-12-18 20:22:06

标签: python python-3.x timeit

我最近注意到关于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的执行时间。我如何处理导入文件(因此失去时间)。

2 个答案:

答案 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

但这种加速不是免费提供的。有两点:

  1. 编译时间增加
  2. .pyc文件大小增加(因为此值存储在.pyc文件中)
  3. 假设我有两个文件:

    #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个文件的大小将为:

    1. foo1.cpython-36.pyc - 364 882 bytes
    2. foo2.cpython-36.pyc - 150个字节

答案 1 :(得分:1)

您最接近的是compileexec一起使用如果您打算作为.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