使用timeit或time计时两个算法(python)

timing two algorithms (python) using timeit or time

我在使用time或timeit函数来确定Python中两个算法的运行时时时遇到一些问题。到目前为止我有这个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def normal(sound):
  for s in getSamples(sound):
    largest=max(0,getSampleValue(s))
    amplification = 32767.0/largest
  for s in getSamples(sound):
    louder = amplification*getSampleValue(s)
    setSampleValue(s,louder)

def onlyMax(sound):
  for s in getSamples(sound):
    value=getSampleValue(s)
    if value>0:
      setSampleValue(s,32767)
    if value<=0:
      setSampleValue(s,-32768)

import time
def timetwoalgorithms(sound):
    print time.time("normal(sound)","onlyMax(sound)")

程序应测量运行每个函数所需的时间,然后输出/打印每个程序的运行时。


time.time()函数不接受任何参数,因为它只是返回当前时间的函数(以自特定时间点(Unix epoch)以来的秒的形式)。您不能使用它来比较这样的两个函数运行时。您可以使用它来测量时间传递,方法是在运行函数之前存储该值,然后将其与随后的time.time()值进行比较,但这是一种糟糕的性能测量方法。

timeit.timeit()函数允许您通过反复执行测试函数以及确保至少最小化可能妨碍精确测量的其他因素来测量测试函数所需的量。但是,一次只能测试一个这样的函数。

要测试一个函数,请传递python source以运行该函数,传递另一个函数以设置测试。该设置应包括导入函数:

1
timeit.timeit("normal(sound)", 'from __main__ import normal, sound')

对另一个函数再次执行此操作,并将结果相互比较。

考虑到函数将被执行多次(您可以调整多少次),所以如果函数改变了全局状态,那么每次都必须重置该状态。这也会改变你衡量绩效的方式。


time.time给出当前时间。你想要时间。时间。

1
2
print(timeit.timeit("normal(sound)"))
print(timeit.timeit("onlyMax(sound)"))

但是,不能将局部变量传递给timeit(使用timeit.timer()时如何传递函数的参数),因此可能需要简化函数。您可以重新实现Timeit:

1
2
3
4
5
def timeit(exec_s, globals={}, number=10000):
    t = time.time()
    for i in range(number):
        exec(exec_s, globals)
    return time.time() - t

并且做

1
2
print(timeit("normal(sound)", locals()))
print(timeit("onlyMax(sound)", locals()))

或者根据@martijn pieers答案将变量放入模块名称空间。或者,将定时回路合并到主功能中:

1
2
3
4
5
6
7
8
9
def time2algorithms(sound, number=10000):
    t = time.time()
    for i in range(number):
        normal(sound)
    print(time.time() - t)
    t = time.time()
    for i in range(number):
        onlyMax(sound)
    print(time.time() - t)