如何测量Python函数的速度

22

我通常在www.codefights.com上作为竞争者编写代码(函数)。所以速度是代码的重要部分之一。如何测量Python语言中某个代码的速度,无论是lambda函数还是def函数。


你可以使用datetime来完成这个任务。 - RaminNietzsche
4
Python提供了 timeit 模块来实现这一功能。 - Christian König
1
使用 timeit 模块。或者使用 time 模块创建自定义计时装饰器。 - Christian Dean
1
你可以使用line_profiler。 - RaminNietzsche
2
如果您的函数运行时间比较长,不希望反复调用它,只需在调用之前使用 start = time.process_time()(或 time.time())获取当前时间,然后在调用之后再次获取当前时间,这样所花费的时间就是差值 time.process_time() - start - ForceBru
显示剩余2条评论
5个回答

21

3步完成 ;)

第1步: 安装 line_profiler

pip install line_profiler

步骤2:在您的代码中添加@profile

from time import sleep

@profile
def so_slow(bar):
    sleep(5)
    return bar

if __name__ == "__main__":
    so_slow(5)

步骤 3:测试您的代码:

kernprof -l -v your_code.py

结果

Wrote profile results to your_code.py.lprof
Timer unit: 1e-06 s

Total time: 5.00283 s
File: your_code.py
Function: so_slow at line 4

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     4                                           @profile
     5                                           def so_slow(bar):
     6         1      5002830 5002830.0    100.0      sleep(5)
     7         1            2      2.0      0.0      return bar

memory_profiler(内存分析工具)

你也可以使用memory_profiler,安装它,添加分析并调用它:

pip install memory_profiler
python -m memory_profiler your_code.py


结果:

Filename: your_code.py

Line #    Mem usage    Increment   Line Contents
================================================
     4   21.289 MiB    0.000 MiB   @profile
     5                             def so_slow(bar):
     6   21.289 MiB    0.000 MiB       sleep(5)
     7   21.289 MiB    0.000 MiB       return bar

更新:

您可以使用objgraph来查找内存泄漏或绘制代码的图形:

from time import sleep

import objgraph
x = [1]

objgraph.show_backrefs([x], filename='sample-backref-graph.png')

def so_slow(bar):
    sleep(5)
    return bar

if __name__ == "__main__":
    so_slow(5)


结果:

图片描述

参考资料: Python性能分析指南


1
你知道如何去除“行内容”吗?我正在尝试读取一个有很多行文本的PDF文件,我不想让它们混杂在我的控制台中。我只需要整个脚本从开始到完成的时间。 - Azurespot

16

请查看Python标准库中的timeit模块:

https://docs.python.org/2/library/timeit.html

>>> import timeit
>>> timeit.timeit('"-".join(str(n) for n in range(100))', number=10000)
0.8187260627746582
>>> timeit.timeit('"-".join([str(n) for n in range(100)])', number=10000)
0.7288308143615723
>>> timeit.timeit('"-".join(map(str, range(100)))', number=10000)
0.5858950614929199

为了让 timeit 模块可以调用您定义的函数,您可以传递一个 setup 参数,其中包含一个 import 语句:

def test():
    """Stupid test function"""
    L = []
    for i in range(100):
        L.append(i)

if __name__ == '__main__':
    import timeit
    print(timeit.timeit("test()", setup="from __main__ import test"))

15

例如:

import timeit

def a():
    return 1+1

print timeit.timeit(a, number=1000000)

2
您可以在IPython中使用它,并使用%time查看执行函数所需的分配时间:
In [1]: def function(a,b):
   ...:     return a+b
   ...: 

In [2]: %time function(1, 2)
CPU times: user 5 µs, sys: 0 ns, total: 5 µs
Wall time: 9.06 µs
Out[2]: 3

2
我通常在需要测量某些非常特定的代码片段的执行时间时,依赖于以下内容: https://docs.python.org/3/library/time.html
def howLong():
    startTime = time.time()
    time.sleep(3)
    print("Time to wake up, ~3 seconds have passed!")
    endTime = time.time()
    
    howMuchTime = endTime - startTime
    print(str(howMuchTime) + " sec")

if __name__ == '__main__':
    import time
    howLong()

结果

Time to wake up, ~3 seconds have passed!
3.013692855834961 sec

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接