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)?
How do I save pr the output of cProfile.Profile () to a *.profile file instead of using pstats.Stats () to analyze and print the profiling results. So I can use it to visually analyze the stats using SnakeViz or similar utilities. The Profile class has a method to write the stats to a file. You can use this to save the output to a file.
The output of cProfile is a binary file that contains all the stats. Python also provides a pstats.Stats class to print the stats to a python shell. Below is an example of how you can use cProfile to profile a piece of code """ Script for using cProfile and pstats to get the stats for your code """ import cProfile import pstats, math pr = cProfile.
The output of cProfile is a binary file that contains all the stats. Python also provides a pstats.Stats class to print the stats to a python shell.
After that, use dump_stats()method to store it to any file by providing the path. # Export profiler output to file stats = pstats.Stats(profiler) stats.dump_stats('/content/export-data') Now, let’s consider a bit more lengthier example to organize the profiler output better.
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.
You don't really need StringIO, as a file qualifies as a stream.
import pstats with open("profilingStatsAsText.txt", "w") as f: ps = pstats.Stats("profilingResults.cprof", stream=f) ps.sort_stats('cumulative') ps.print_stats()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With