Show More
@@ -0,0 +1,90 b'' | |||||
|
1 | """ | |||
|
2 | lsprofcalltree.py - lsprof output which is readable by kcachegrind | |||
|
3 | ||||
|
4 | Authors: | |||
|
5 | * David Allouche <david <at> allouche.net> | |||
|
6 | * Jp Calderone & Itamar Shtull-Trauring | |||
|
7 | * Johan Dahlin | |||
|
8 | ||||
|
9 | This software may be used and distributed according to the terms | |||
|
10 | of the GNU General Public License, incorporated herein by reference. | |||
|
11 | """ | |||
|
12 | ||||
|
13 | import optparse | |||
|
14 | import os | |||
|
15 | import sys | |||
|
16 | ||||
|
17 | def label(code): | |||
|
18 | if isinstance(code, str): | |||
|
19 | return '~' + code # built-in functions ('~' sorts at the end) | |||
|
20 | else: | |||
|
21 | return '%s %s:%d' % (code.co_name, | |||
|
22 | code.co_filename, | |||
|
23 | code.co_firstlineno) | |||
|
24 | ||||
|
25 | class KCacheGrind(object): | |||
|
26 | def __init__(self, profiler): | |||
|
27 | self.data = profiler.getstats() | |||
|
28 | self.out_file = None | |||
|
29 | ||||
|
30 | def output(self, out_file): | |||
|
31 | self.out_file = out_file | |||
|
32 | print >> out_file, 'events: Ticks' | |||
|
33 | self._print_summary() | |||
|
34 | for entry in self.data: | |||
|
35 | self._entry(entry) | |||
|
36 | ||||
|
37 | def _print_summary(self): | |||
|
38 | max_cost = 0 | |||
|
39 | for entry in self.data: | |||
|
40 | totaltime = int(entry.totaltime * 1000) | |||
|
41 | max_cost = max(max_cost, totaltime) | |||
|
42 | print >> self.out_file, 'summary: %d' % (max_cost,) | |||
|
43 | ||||
|
44 | def _entry(self, entry): | |||
|
45 | out_file = self.out_file | |||
|
46 | ||||
|
47 | code = entry.code | |||
|
48 | #print >> out_file, 'ob=%s' % (code.co_filename,) | |||
|
49 | if isinstance(code, str): | |||
|
50 | print >> out_file, 'fi=~' | |||
|
51 | else: | |||
|
52 | print >> out_file, 'fi=%s' % (code.co_filename,) | |||
|
53 | print >> out_file, 'fn=%s' % (label(code),) | |||
|
54 | ||||
|
55 | inlinetime = int(entry.inlinetime * 1000) | |||
|
56 | if isinstance(code, str): | |||
|
57 | print >> out_file, '0 ', inlinetime | |||
|
58 | else: | |||
|
59 | print >> out_file, '%d %d' % (code.co_firstlineno, inlinetime) | |||
|
60 | ||||
|
61 | # recursive calls are counted in entry.calls | |||
|
62 | if entry.calls: | |||
|
63 | calls = entry.calls | |||
|
64 | else: | |||
|
65 | calls = [] | |||
|
66 | ||||
|
67 | if isinstance(code, str): | |||
|
68 | lineno = 0 | |||
|
69 | else: | |||
|
70 | lineno = code.co_firstlineno | |||
|
71 | ||||
|
72 | for subentry in calls: | |||
|
73 | self._subentry(lineno, subentry) | |||
|
74 | print >> out_file | |||
|
75 | ||||
|
76 | def _subentry(self, lineno, subentry): | |||
|
77 | out_file = self.out_file | |||
|
78 | code = subentry.code | |||
|
79 | #print >> out_file, 'cob=%s' % (code.co_filename,) | |||
|
80 | print >> out_file, 'cfn=%s' % (label(code),) | |||
|
81 | if isinstance(code, str): | |||
|
82 | print >> out_file, 'cfi=~' | |||
|
83 | print >> out_file, 'calls=%d 0' % (subentry.callcount,) | |||
|
84 | else: | |||
|
85 | print >> out_file, 'cfi=%s' % (code.co_filename,) | |||
|
86 | print >> out_file, 'calls=%d %d' % ( | |||
|
87 | subentry.callcount, code.co_firstlineno) | |||
|
88 | ||||
|
89 | totaltime = int(subentry.totaltime * 1000) | |||
|
90 | print >> out_file, '%d %d' % (lineno, totaltime) |
@@ -552,6 +552,10 b' profiling::' | |||||
552 | Generate a profiling report. |
|
552 | Generate a profiling report. | |
553 | When saving to a file, it should be noted that only the report is saved, |
|
553 | When saving to a file, it should be noted that only the report is saved, | |
554 | and the profiling data is not kept. |
|
554 | and the profiling data is not kept. | |
|
555 | kcachegrind;; | |||
|
556 | Format profiling data for kcachegrind use: | |||
|
557 | when saving to a file, the generated file can directly be loaded | |||
|
558 | into kcachegrind. | |||
555 | output;; |
|
559 | output;; | |
556 | File path where profiling data or report should be saved. |
|
560 | File path where profiling data or report should be saved. | |
557 | If the file exists, it is replaced. |
|
561 | If the file exists, it is replaced. |
@@ -381,7 +381,7 b' def _runcommand(ui, options, cmd, cmdfun' | |||||
381 | if options['profile']: |
|
381 | if options['profile']: | |
382 | format = ui.config('profiling', 'format', default='text') |
|
382 | format = ui.config('profiling', 'format', default='text') | |
383 |
|
383 | |||
384 | if not format in ['text']: |
|
384 | if not format in ['text', 'kcachegrind']: | |
385 | ui.warn(_("unrecognized profiling format '%s'" |
|
385 | ui.warn(_("unrecognized profiling format '%s'" | |
386 | " - Ignored\n") % format) |
|
386 | " - Ignored\n") % format) | |
387 | format = 'text' |
|
387 | format = 'text' | |
@@ -407,9 +407,16 b' def _runcommand(ui, options, cmd, cmdfun' | |||||
407 | return checkargs() |
|
407 | return checkargs() | |
408 | finally: |
|
408 | finally: | |
409 | p.disable() |
|
409 | p.disable() | |
410 | stats = lsprof.Stats(p.getstats()) |
|
410 | ||
411 | stats.sort() |
|
411 | if format == 'kcachegrind': | |
412 | stats.pprint(top=10, file=ostream, climit=5) |
|
412 | import lsprofcalltree | |
|
413 | calltree = lsprofcalltree.KCacheGrind(p) | |||
|
414 | calltree.output(ostream) | |||
|
415 | else: | |||
|
416 | # format == 'text' | |||
|
417 | stats = lsprof.Stats(p.getstats()) | |||
|
418 | stats.sort() | |||
|
419 | stats.pprint(top=10, file=ostream, climit=5) | |||
413 |
|
420 | |||
414 | if output: |
|
421 | if output: | |
415 | ostream.close() |
|
422 | ostream.close() |
@@ -18,4 +18,15 b' if "$TESTDIR/hghave" -q lsprof; then' | |||||
18 |
|
18 | |||
19 | hg --profile --config profiling.format=text st 2>&1 \ |
|
19 | hg --profile --config profiling.format=text st 2>&1 \ | |
20 | | grep CallCount > /dev/null || echo --profile format=text failed |
|
20 | | grep CallCount > /dev/null || echo --profile format=text failed | |
|
21 | ||||
|
22 | echo "[profiling]" >> $HGRCPATH | |||
|
23 | echo "format=kcachegrind" >> $HGRCPATH | |||
|
24 | ||||
|
25 | hg --profile st 2>../out || echo --profile format=kcachegrind failed | |||
|
26 | grep 'events: Ticks' < ../out > /dev/null || echo --profile output is wrong | |||
|
27 | ||||
|
28 | hg --profile --config profiling.output=../out st 2>&1 \ | |||
|
29 | || echo --profile format=kcachegrind + output to file failed | |||
|
30 | grep 'events: Ticks' < ../out > /dev/null \ | |||
|
31 | || echo --profile output is wrong | |||
21 | fi |
|
32 | fi |
General Comments 0
You need to be logged in to leave comments.
Login now