mercurial/lsprofcalltree.py
author Martin von Zweigbergk <martinvonz@google.com>
Tue, 08 Dec 2020 23:05:53 -0800
changeset 46100 fd75e5c53ec3
parent 43077 687b865b95ad
child 48966 6000f5b25c9b
permissions -rw-r--r--
simplemerge: avoid quadratic concatenation when building output text I haven't checked if the difference is measurable, but the new version is no less readable or idiomatic, so I don't think performance numbers are needed. Differential Revision: https://phab.mercurial-scm.org/D9549
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8024
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
     1
"""
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
     2
lsprofcalltree.py - lsprof output which is readable by kcachegrind
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
     3
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
     4
Authors:
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
     5
    * David Allouche <david <at> allouche.net>
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
     6
    * Jp Calderone & Itamar Shtull-Trauring
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
     7
    * Johan Dahlin
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
     8
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
     9
This software may be used and distributed according to the terms
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    10
of the GNU General Public License, incorporated herein by reference.
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    11
"""
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    12
40194
1ae0faa14797 py3: use write() instead of print()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27618
diff changeset
    13
from __future__ import absolute_import
27505
071af8d385a9 lsprofcalltree: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 8390
diff changeset
    14
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40195
diff changeset
    15
from . import pycompat
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40195
diff changeset
    16
40195
720355c7b7c9 py3: use sysbytes for converting code attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40194
diff changeset
    17
8024
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    18
def label(code):
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    19
    if isinstance(code, str):
40195
720355c7b7c9 py3: use sysbytes for converting code attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40194
diff changeset
    20
        # built-in functions ('~' sorts at the end)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    21
        return b'~' + pycompat.sysbytes(code)
8024
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    22
    else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    23
        return b'%s %s:%d' % (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40195
diff changeset
    24
            pycompat.sysbytes(code.co_name),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40195
diff changeset
    25
            pycompat.sysbytes(code.co_filename),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40195
diff changeset
    26
            code.co_firstlineno,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40195
diff changeset
    27
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40195
diff changeset
    28
8024
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    29
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    30
class KCacheGrind(object):
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    31
    def __init__(self, profiler):
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    32
        self.data = profiler.getstats()
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    33
        self.out_file = None
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    34
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    35
    def output(self, out_file):
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    36
        self.out_file = out_file
40194
1ae0faa14797 py3: use write() instead of print()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27618
diff changeset
    37
        out_file.write(b'events: Ticks\n')
8024
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    38
        self._print_summary()
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    39
        for entry in self.data:
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    40
            self._entry(entry)
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    41
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    42
    def _print_summary(self):
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    43
        max_cost = 0
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    44
        for entry in self.data:
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    45
            totaltime = int(entry.totaltime * 1000)
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    46
            max_cost = max(max_cost, totaltime)
40194
1ae0faa14797 py3: use write() instead of print()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27618
diff changeset
    47
        self.out_file.write(b'summary: %d\n' % max_cost)
8024
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    48
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    49
    def _entry(self, entry):
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    50
        out_file = self.out_file
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    51
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    52
        code = entry.code
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    53
        if isinstance(code, str):
40194
1ae0faa14797 py3: use write() instead of print()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27618
diff changeset
    54
            out_file.write(b'fi=~\n')
8024
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    55
        else:
40195
720355c7b7c9 py3: use sysbytes for converting code attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40194
diff changeset
    56
            out_file.write(b'fi=%s\n' % pycompat.sysbytes(code.co_filename))
40194
1ae0faa14797 py3: use write() instead of print()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27618
diff changeset
    57
1ae0faa14797 py3: use write() instead of print()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27618
diff changeset
    58
        out_file.write(b'fn=%s\n' % label(code))
8024
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    59
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    60
        inlinetime = int(entry.inlinetime * 1000)
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    61
        if isinstance(code, str):
40194
1ae0faa14797 py3: use write() instead of print()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27618
diff changeset
    62
            out_file.write(b'0 %d\n' % inlinetime)
8024
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    63
        else:
40194
1ae0faa14797 py3: use write() instead of print()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27618
diff changeset
    64
            out_file.write(b'%d %d\n' % (code.co_firstlineno, inlinetime))
8024
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    65
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    66
        # recursive calls are counted in entry.calls
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    67
        if entry.calls:
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    68
            calls = entry.calls
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    69
        else:
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    70
            calls = []
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    71
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    72
        if isinstance(code, str):
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    73
            lineno = 0
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    74
        else:
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    75
            lineno = code.co_firstlineno
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    76
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    77
        for subentry in calls:
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    78
            self._subentry(lineno, subentry)
40194
1ae0faa14797 py3: use write() instead of print()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27618
diff changeset
    79
1ae0faa14797 py3: use write() instead of print()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27618
diff changeset
    80
        out_file.write(b'\n')
8024
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    81
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    82
    def _subentry(self, lineno, subentry):
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    83
        out_file = self.out_file
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    84
        code = subentry.code
40194
1ae0faa14797 py3: use write() instead of print()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27618
diff changeset
    85
        out_file.write(b'cfn=%s\n' % label(code))
8024
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    86
        if isinstance(code, str):
40194
1ae0faa14797 py3: use write() instead of print()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27618
diff changeset
    87
            out_file.write(b'cfi=~\n')
1ae0faa14797 py3: use write() instead of print()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27618
diff changeset
    88
            out_file.write(b'calls=%d 0\n' % subentry.callcount)
8024
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    89
        else:
40195
720355c7b7c9 py3: use sysbytes for converting code attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40194
diff changeset
    90
            out_file.write(b'cfi=%s\n' % pycompat.sysbytes(code.co_filename))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40195
diff changeset
    91
            out_file.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40195
diff changeset
    92
                b'calls=%d %d\n' % (subentry.callcount, code.co_firstlineno)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40195
diff changeset
    93
            )
8024
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    94
9a1b86cfd29e profiling: Adding support for kcachegrind output format, using lsprofcalltree
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
diff changeset
    95
        totaltime = int(subentry.totaltime * 1000)
40194
1ae0faa14797 py3: use write() instead of print()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27618
diff changeset
    96
        out_file.write(b'%d %d\n' % (lineno, totaltime))