python计时函数timeit.timeit()使用小结

Python提供了一个timeit.timeit()函数用于计算函数的运行时间,这使得我们在项目开发中很方便的设计profiling并根据结果做相应的优化, 其定义如下:

timeit.timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000)
    Create a Timer instance with the given statement, setup code and timer function and run its timeit() method with number executions.

    New in version 2.6.

例如,假设我们在某个项目中要统计并存储访问过的url,一个可能的实现如下所示:

 1 class UrlStatistics:
 2     def __init__(self):
 3         self.visitedSites = dict()
 4 
 5     def visit(self, url):
 6         if url in self.visitedSites:
 7             self.visitedSites[url] += 1
 8         else:
 9             self.visitedSites[url] = 1
10         
11     def mostFrequentVisitedSites(self, n=10):
12         sortedSites = sorted(self.visitedSites.items(),
13                              key=lambda pair: pair[1], reverse=True)
14         return [(url, visits) for url, visits in sortedSites[:n]]

上面示例代码中用一个dict变量存储所有访问过的url(line 2), 函数visit() 将每一个新访问的的url计入我们的统计当中(line5~9), 函数mostFrequentVisitedSites()返回访问最频繁的前十名url(line 11~14). 为了使用timeit.timeit()函数计算visit()或mostFrequentVisitedSites()执行效率,我们需要让该函数反复执行,因此我们还需要以某种方式来反复得到不同或相同的URL。 下面的get_url_name()函数随机从英文字母表选取3-7个字符并拼接成URL, test_visit()函数用于调用UrlStatistics.visit(), 最后我们用timeit.timeit()调用test_visit()函数并设定调用次数,最后得到运行时间:

 1 def get_url_name():
 2     prefix = 'www'
 3     suffix = 'com'
 4     name = ''.join([random.choice(string.ascii_lowercase)
 5                        for i in range(random.randint(3, 7))])
 6     return '.'.join([prefix, name, suffix])
 7 
 8 
 9 def test_visit():
10     urlStats = UrlStatistics()
11     urlStats.visit(get_url_name())
12 
13 
14 if __name__ == '__main__':
15     print(timeit.timeit('test_visit()',
16                         setup='from __main__ import test_visit',
17                         number=600000))

结果如下:

stephenw@stephenw-devbox1:~/pyTest$ ./timeitTest.py
8.078887998002756

考虑到python中collections模块中的defaultdict可以让visit()函数看上去更简洁,我们可做如下修改:

class UrlStatistics:
    def __init__(self):
        self.visitedSites = defaultdict(int)

    def visit(self, url):
        self.visitedSites[url] += 1

相应的,由timeit.timeit()得到的运行时间为 8.326297112002067, 可见使用defaultdict()后,效率降低了

最后,timeit模块还提供了命令行接口来实现同样的功能(结果和上面略有差异):

stephenw@stephenw-devbox1:~/pyTest$  python -m timeit -n 600000 "from timeitTest import test_visit; test_visit()"
600000 loops, best of 3: 9.83 usec per loop

  

 

posted on 2019-05-20 10:35  wangwenzhi2019  阅读(1631)  评论(0编辑  收藏  举报

导航