首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用timeit模块

如何使用timeit模块
EN

Stack Overflow用户
提问于 2011-11-22 09:15:01
回答 14查看 357.9K关注 0票数 412

我理解timeit功能的概念,但我不确定如何在我的代码中实现它。

如何使用timeit比较两个函数,比如insertion_sorttim_sort

EN

回答 14

Stack Overflow用户

回答已采纳

发布于 2011-11-22 09:38:10

的工作方式是运行一次设置代码,然后重复调用一系列语句。因此,如果您想要测试排序,需要注意的是,在就地排序中的一次传递不会影响已经排序的数据的下一次传递(当然,这将使Timsort真正发光,因为当数据已经部分排序时,它的性能最好)。

以下是如何设置测试以进行排序的示例:

代码语言:javascript
复制
>>> import timeit

>>> setup = '''
import random

random.seed('slartibartfast')
s = [random.random() for i in range(1000)]
timsort = list.sort
'''

>>> print min(timeit.Timer('a=s[:]; timsort(a)', setup=setup).repeat(7, 1000))
0.334147930145

请注意,这一系列语句在每次遍历时都会生成未排序数据的新副本。

此外,请注意七次运行测量套件并只保留最佳时间的计时技术--这确实有助于减少由于系统上运行的其他进程而导致的测量失真。

这些是我正确使用timeit的小贴士。希望这能有所帮助:-)

票数 303
EN

Stack Overflow用户

发布于 2011-11-22 09:41:49

如果您想在交互式timeit会话中使用Python,有两个方便的选择:

  1. 使用IPython外壳。它的特点是方便的%timeit特殊功能:

in 1: def (X):...:return x*x...:In 2:%timeit x in range(100):f(x) 100000个循环,最好是3: 20.3us

  • 在标准的Python解释器中,您可以通过在setup statement:def f(x):...中从__main__导入函数和其他名称来访问之前在交互会话期间定义的函数和其他名称。2.0520210266113281

x*x... >>> import timeit >>> timeit.repeat("for x in range(100):f(x)","from __main__ import f",number=100000) 2.0640320777893066,2.0876040458679199,>>>

票数 309
EN

Stack Overflow用户

发布于 2014-06-08 19:51:44

我将告诉您一个秘密:使用timeit的最佳方式是在命令行上。

在命令行上,timeit会进行适当的统计分析:它会告诉您最短的运行花费了多长时间。这是好的,因为计时中的所有误差都是正的。所以最短的时间误差最小。没有办法得到负错误,因为计算机的计算速度永远不会超过它的计算速度!

因此,命令行界面:

代码语言:javascript
复制
%~> python -m timeit "1 + 2"
10000000 loops, best of 3: 0.0468 usec per loop

这很简单,对吧?

你可以设置一些东西:

代码语言:javascript
复制
%~> python -m timeit -s "x = range(10000)" "sum(x)"
1000 loops, best of 3: 543 usec per loop

这也很有用!

如果您想要多行,您可以使用shell的自动延续或使用单独的参数:

代码语言:javascript
复制
%~> python -m timeit -s "x = range(10000)" -s "y = range(100)" "sum(x)" "min(y)"
1000 loops, best of 3: 554 usec per loop

这给出了一个设置

代码语言:javascript
复制
x = range(1000)
y = range(100)

和时间

代码语言:javascript
复制
sum(x)
min(y)

如果您想要更长的脚本,您可能会尝试在Python脚本中使用timeit。我建议避免这样做,因为在命令行上进行分析和计时会更好。相反,我倾向于编写shell脚本:

代码语言:javascript
复制
 SETUP="

 ... # lots of stuff

 "

 echo Minmod arr1
 python -m timeit -s "$SETUP" "Minmod(arr1)"

 echo pure_minmod arr1
 python -m timeit -s "$SETUP" "pure_minmod(arr1)"

 echo better_minmod arr1
 python -m timeit -s "$SETUP" "better_minmod(arr1)"

 ... etc

由于多个初始化,这可能需要更长的时间,但通常这不是什么大问题。

但是如果你想在你的模块中使用timeit呢?

嗯,简单的方法是这样做:

代码语言:javascript
复制
def function(...):
    ...

timeit.Timer(function).timeit(number=NUMBER)

这给了你累积性(不是最小的!)运行该次数所需的时间。

要获得良好的分析结果,请使用.repeat并取最小值:

代码语言:javascript
复制
min(timeit.Timer(function).repeat(repeat=REPEATS, number=NUMBER))

通常情况下,您应该将其与functools.partial而不是lambda: ...结合使用,以降低开销。因此,你可能会有类似这样的东西:

代码语言:javascript
复制
from functools import partial

def to_time(items):
    ...

test_items = [1, 2, 3] * 100
times = timeit.Timer(partial(to_time, test_items)).repeat(3, 1000)

# Divide by the number of repeats
time_taken = min(times) / 1000

您还可以执行以下操作:

代码语言:javascript
复制
timeit.timeit("...", setup="from __main__ import ...", number=NUMBER)

这将使您从命令行获得更接近界面的东西,但以一种不太酷的方式。"from __main__ import ..."允许您在timeit创建的人工环境中使用主模块中的代码。

值得注意的是,这是一个方便的Timer(...).timeit(...)包装器,因此在计时方面不是特别好。就我个人而言,我更喜欢使用上面提到的Timer(...).repeat(...)

警告

timeit有一些随处可见的警告。

不考虑

  • 开销。假设您想对x += 1进行计时,以找出增加takes:python -m timeit -s "x = 0“"x += 1”10000000个循环的时间,每个循环最好3: 0.0476微秒

嗯,它不是0.0476微秒。你只知道它小于这个数字。所有错误都是肯定的。

所以试着找到纯粹的开销:

python -m timeit -s "x = 0“”100000000次循环,每个循环最好3: 0.014微秒

这是一个很好的,仅从时间上就有30%的开销!这会极大地扭曲相对计时。但您真正关心的是添加时间;x的查找时间也需要包含在开销中:

python -m timeit -s "x = 0“"x”100000000个循环,每个循环最好3: 0.0166微秒

差别不是很大,但它的there.

  • Mutating方法是dangerous.python -m timeit -s "x = *100000“"while x: x.pop()”10000000个循环,最好是每个循环3: 0.0436微秒

但这是完全错误的!x是第一次迭代后的空列表。您将需要重新初始化:

python -m timeit "x = *100000“"while x: x.pop()”100次循环,最好的3次循环: 9.79毫秒

但是你会有很多开销。单独说明这点。

python -m timeit "x = *100000“1000个循环,每个循环最好3: 261微秒

请注意,在这里减去开销是合理的,因为开销只占时间的一小部分。

对于您的示例,值得注意的是,对于已经排序的列表,插入排序和Tim排序都有完全不寻常的计时行为。这意味着,如果您希望避免破坏timings.,则需要在排序之间使用random.shuffle

票数 162
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8220801

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档