-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprofile.py
90 lines (71 loc) · 2.06 KB
/
profile.py
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/usr/bin/env python
"""
A profiler decorator.
Author: Giampaolo Rodola' <g.rodola [AT] gmail [DOT] com>
License: MIT
"""
import cProfile
import tempfile
import pstats
def profile(sort="cumulative", lines=50, strip_dirs=False):
"""A decorator which profiles a callable.
Example usage:
>>> @profile
def factorial(n):
n = abs(int(n))
if n < 1:
n = 1
x = 1
for i in range(1, n + 1):
x = i * x
return x
...
>>> factorial(5)
Thu Jul 15 20:58:21 2010 /tmp/tmpIDejr5
4 function calls in 0.000 CPU seconds
Ordered by: internal time, call count
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 profiler.py:120(factorial)
1 0.000 0.000 0.000 0.000 {range}
1 0.000 0.000 0.000 0.000 {abs}
120
>>>
"""
def outer(fun):
def inner(*args, **kwargs):
file = tempfile.NamedTemporaryFile()
prof = cProfile.Profile()
try:
ret = prof.runcall(fun, *args, **kwargs)
except:
file.close()
raise
prof.dump_stats(file.name)
stats = pstats.Stats(file.name)
if strip_dirs:
stats.strip_dirs()
if isinstance(sort, (tuple, list)):
stats.sort_stats(*sort)
else:
stats.sort_stats(sort)
stats.print_stats(lines)
file.close()
return ret
return inner
# in case this is defined as "@profile" instead of "@profile()"
if hasattr(sort, "__call__"):
fun = sort
sort = "cumulative"
outer = outer(fun)
return outer
if __name__ == "__main__":
@profile
def factorial(n):
n = abs(int(n))
if n < 1:
n = 1
x = 1
for i in range(1, n + 1):
x = i * x
return x
factorial(10)