Py性能分析示例

1.time.time() 简单的计时器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/python
import time
def timefunc(f):
def f_timer(*args, **kwargs):
start = time.time()
result = f(*args, **kwargs)
end = time.time()
print f.__name__, 'took', end - start, 'time'
return result
return f_timer


@timefunc
def test():
for i in xrange(100):
print i

test()

2.timeit模块

2.1.python shell中使用

1
2
import timeit
timeit.timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000)

2.2 脚本中使用

1
2
3
4
5
6
7
8
#!/usr/bin/python
import timeit
def test():
for i in xrange(1000):
print i

if __name__ == '__main__':
timeit.timeit('test()', setup='from __main__ import test', number=1)

3.cProfile

python -m cProfile -s cumulative a.py

4.linux time命令

1
2
3
4
/usr/bin/time -f "Memory: %M bytes" python script.py

Time using for-loop: 0.155635 seconds
Memory: 66212 bytes

5.line_profiler 每行比对 调用次数 耗时

适用于分析单独函数
安装 pip install line_profiler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import line_profiler
import sys

def fib(n):
a, b = 0, 1
for i in range(0, n):
a, b = b, a + b
return a


prof = line_profiler.LineProfiler(fib)
prof.enable()
fib(100)
prof.disable()
prof.print_stats(sys.stdout)

执行
kernprof -l -v script_to_profile.py
查看pstat
python -m line_profiler stats_file.py.lprof

6.memory_profiler模块 分析内存使用情况

1
2
3
4
5
6
7
8
9
class Foobar(object):
def __init__(self, x):
self.x = x

@profile
def main():
f = [ Foobar(i) for i in range(100000) ]
if __name__ == '__main__':
main()

执行
python -m memory_profiler example.py

7.bytecode 字节码

dis模块

1
2
3
4
5
6
7
>>> def x():
... return 42
...
>>> import dis
>>> dis.dis(x)
2 0 LOAD_CONST 1 (42)
3 RETURN_VALUE

8.性能分析装饰器定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import cProfile
import pstats
import os
def do_cprofile(func):
def wrapper(*args, **kwargs):
profile = cProfile.Profile()
# 开始收集性能分析数据
profile.enable()
result = func(*args, **kwargs)
# 停止收集性能分析数据
profile.disable()
# Sort stat by internal time.
sortby = "tottime"
# 对报告列表进行排序
ps = pstats.Stats(profile).sort_stats(sortby)
# 把信息打印到标准输出
ps.print_stats()
return result
return wrapper


@do_cprofile
def test():
for i in range(100):
print(i)

if __name__ == '__main__':
test()

9.利用cProfile+gprof2dot可视化

具体参考:

https://ephrain.net/python-%E7%94%A8-cprofilegprof2dot-%E5%B0%87-profiling-%E7%B5%90%E6%9E%9C%E8%A6%96%E8%A6%BA%E5%8C%96

https://github.com/jrfonseca/gprof2dot

坚持原创技术分享,您的支持将鼓励我继续创作!