1 | |
---|
2 | import cProfile, pstats, os |
---|
3 | def func_std_string(func_name): # match what old profile produced |
---|
4 | if func_name[:2] == ('~', 0): |
---|
5 | # special case for built-in functions |
---|
6 | name = func_name[2] |
---|
7 | if name.startswith('<') and name.endswith('>'): |
---|
8 | return '{%s}' % name[1:-1] |
---|
9 | else: |
---|
10 | return name |
---|
11 | else: |
---|
12 | return "%s:%d(%s)" % func_name |
---|
13 | |
---|
14 | def f8(x): |
---|
15 | return "%8.3f" % x |
---|
16 | |
---|
17 | class CustomPstats(pstats.Stats): |
---|
18 | def __init__(self, *args, **kwds): |
---|
19 | pstats.Stats.__init__(self, *args, **kwds) |
---|
20 | |
---|
21 | def write_stats(self, *amount): |
---|
22 | msg = '' |
---|
23 | for filename in self.files: |
---|
24 | msg += str(filename) + '\n' |
---|
25 | #if self.files: msg += str(self.stream) + '\n' |
---|
26 | indent = ' ' * 8 |
---|
27 | for func in self.top_level: |
---|
28 | msg += str(indent)+ str(func_get_function_name(func))+"\n" |
---|
29 | |
---|
30 | msg += str(indent) + str(self.total_calls)+ "function calls" + '\n' |
---|
31 | if self.total_calls != self.prim_calls: |
---|
32 | msg += "(%d primitive calls)" % self.prim_calls + '\n' |
---|
33 | msg += "in %.3f CPU seconds" % self.total_tt + '\n' |
---|
34 | #msg += str(self.stream) + '\n' |
---|
35 | |
---|
36 | width = self.max_name_len |
---|
37 | if self.fcn_list: |
---|
38 | stats = self.fcn_list[:] |
---|
39 | temp_msg = " Ordered by: " + self.sort_type + '\n' |
---|
40 | else: |
---|
41 | stats = list(self.stats.keys()) |
---|
42 | temp_msg = " Random listing order was used\n" |
---|
43 | |
---|
44 | for selection in amount: |
---|
45 | stats, temp_msg = self.eval_print_amount(selection, stats, temp_msg) |
---|
46 | |
---|
47 | count = len(stats) |
---|
48 | |
---|
49 | if not stats: |
---|
50 | width = 0 |
---|
51 | else: |
---|
52 | msg += str(temp_msg) + '\n' |
---|
53 | if count < len(self.stats): |
---|
54 | width = 0 |
---|
55 | for func in stats: |
---|
56 | if len(func_std_string(func)) > width: |
---|
57 | width = len(func_std_string(func)) |
---|
58 | |
---|
59 | width = width+2 |
---|
60 | if stats: |
---|
61 | msg += ' ncalls tottime percall cumtime percall' |
---|
62 | msg += ' filename:lineno(function)' + "\n" |
---|
63 | for func in stats: |
---|
64 | cc, nc, tt, ct, callers = self.stats[func] |
---|
65 | c = str(nc) |
---|
66 | if nc != cc: |
---|
67 | c = c + '/' + str(cc) |
---|
68 | msg += str( c.rjust(9)) |
---|
69 | msg += str(f8(tt)) |
---|
70 | if nc == 0: |
---|
71 | msg += str(' '*8) |
---|
72 | else: |
---|
73 | msg += str(f8(tt/nc)) |
---|
74 | msg += str(f8(ct)) |
---|
75 | if cc == 0: |
---|
76 | msg += str( ' '*80) |
---|
77 | else: |
---|
78 | msg += str(f8(ct/cc)) |
---|
79 | msg += " " + str(func_std_string(func)) + '\n' |
---|
80 | msg += str(self.stream) + '\n' |
---|
81 | #msg += str(self.stream) + '\n' |
---|
82 | return self, msg |
---|
83 | |
---|
84 | def profile( fn, name='profile.txt',*args, **kw): |
---|
85 | import cProfile, pstats, os |
---|
86 | global call_result |
---|
87 | def call(): |
---|
88 | global call_result |
---|
89 | call_result = fn(*args, **kw) |
---|
90 | cProfile.runctx('call()', dict(call=call), {}, 'profile.txt') |
---|
91 | stats = CustomPstats('profile.txt') |
---|
92 | #sort by cumlative time |
---|
93 | stats.sort_stats('time') |
---|
94 | stats.print_stats(50) |
---|
95 | """ |
---|
96 | filename = 'profile_cum_' + name |
---|
97 | _, msg = stats.write_stats(50) |
---|
98 | f = file(filename, 'wb') |
---|
99 | f.write(msg) |
---|
100 | f.close() |
---|
101 | #sort by time |
---|
102 | stats.sort_stats('time') |
---|
103 | _, msg = stats.write_stats(50) |
---|
104 | filename = 'profile_time_' + name |
---|
105 | f = file(filename, 'wb') |
---|
106 | f.write(msg) |
---|
107 | f.close() |
---|
108 | # sort by number of calls |
---|
109 | stats.sort_stats('call') |
---|
110 | _, msg = stats.write_stats(50) |
---|
111 | filename = 'profile_call_' + name |
---|
112 | f = file(filename, 'wb') |
---|
113 | f.write(msg) |
---|
114 | f.close() |
---|
115 | os.unlink('profile.txt') |
---|
116 | """ |
---|
117 | return call_result |
---|
118 | |
---|