将 cProfile 结果保存到可读的外部文件 [英] saving cProfile results to readable external file
问题描述
我正在使用 cProfile
尝试分析我的代码:
pr = cProfile.Profile()启用()my_func() # 我要分析的代码pr.disable()pr.print_stats()
但是结果太长,无法在Spyder终端完全显示出来(运行时间最长的函数调用看不到...).我也尝试使用
保存结果 cProfile.run('my_func()','profile_results')
但输出文件不是人类可读的格式(尝试使用和不使用 .txt
后缀).
所以我的问题是如何将分析结果保存到人类可读的外部文件中(例如以 .txt
格式正确显示所有单词)?
已更新. 您可以使用
您还可以轻松对结果进行排序:
p.strip_dirs().sort_stats('tottime').print_stats()p.strip_dirs().sort_stats('cumulative').print_stats()p.strip_dirs().sort_stats().print_stats('mod1')
希望这会有所帮助.
I am using cProfile
try to profile my codes:
pr = cProfile.Profile()
pr.enable()
my_func() # the code I want to profile
pr.disable()
pr.print_stats()
However, the results are too long and cannot be fully displayed in the Spyder terminal (the function calls which take the longest time to run cannot be seen...). I also tried saving the results using
cProfile.run('my_func()','profile_results')
but the output file is not in human readable format (tried with and without .txt
suffix).
So my question is how can I save the profiling results to an external file which is human readable (like in a .txt
format with all the words properly displayed)?
Updated. You can get output of profiler using io.StringIO() and save it into file. Here is an example:
import cProfile
import pstats
import io
def my_func():
result = []
for i in range(10000):
result.append(i)
return result
pr = cProfile.Profile()
pr.enable()
my_result = my_func()
pr.disable()
s = io.StringIO()
ps = pstats.Stats(pr, stream=s).sort_stats('tottime')
ps.print_stats()
with open('test.txt', 'w+') as f:
f.write(s.getvalue())
Run our script and open test.txt
. You will see readable result:
10002 function calls in 0.003 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.002 0.002 0.003 0.003 /path_to_script.py:26(my_func)
10000 0.001 0.000 0.001 0.000 {method 'append' of 'list' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
Also I can recommend to use dump_stats + pstats.Stats. Here is an example how to use it. Structure of files:
# test_ex.py - just a small web app
import cProfile
import json
from functools import wraps
from flask import Flask
from example.mod1 import func1
from example.mod2 import func2
app = Flask(__name__)
# profiling decorator
def profiling():
def _profiling(f):
@wraps(f)
def __profiling(*rgs, **kwargs):
pr = cProfile.Profile()
pr.enable()
result = f(*rgs, **kwargs)
pr.disable()
# save stats into file
pr.dump_stats('profile_dump')
return result
return __profiling
return _profiling
# demonstration route with profiler
@app.route('/test')
@profiling()
def test():
counter = func1()
dict_data = func2()
result = dict()
for key, val in dict_data.items():
result[key] = val + counter
return json.dumps(result)
if __name__ == '__main__':
app.run(debug=True, port=8083)
example package - let's imagine that this is some kind of application logic.
# example.mod1
def func1():
counter = 0
for i in range(100000):
counter += i
return counter
# example.mod2
def func2():
res = dict()
for i in range(300000):
res['key_' + str(i)] = i
return res
Now let's run server(python3 test_ex.py
) and open http://localhost:8083/test
. After a few seconds you will see long json. After that you will see profile_dump file in project folder. Now run python live interpreter in project folder and print our dump using pstats:
import pstats
p = pstats.Stats('profile_dump')
# skip strip_dirs() if you want to see full path's
p.strip_dirs().print_stats()
Also you can easy sorting results:
p.strip_dirs().sort_stats('tottime').print_stats()
p.strip_dirs().sort_stats('cumulative').print_stats()
p.strip_dirs().sort_stats().print_stats('mod1')
Hope this helps.
这篇关于将 cProfile 结果保存到可读的外部文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!