/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to profile_imports.py

  • Committer: Robert Collins
  • Date: 2007-04-19 02:27:44 UTC
  • mto: This revision was merged to the branch mainline in revision 2426.
  • Revision ID: robertc@robertcollins.net-20070419022744-pfdqz42kp1wizh43
``make docs`` now creates a man page at ``man1/bzr.1`` fixing bug 107388.
(Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006, 2008, 2009, 2010 by Canonical Ltd
 
1
# Copyright (C) 2006 by Canonical Ltd
2
2
# Written by John Arbash Meinel <john@arbash-meinel.com>
3
3
#
4
4
# This program is free software; you can redistribute it and/or modify
13
13
#
14
14
# You should have received a copy of the GNU General Public License
15
15
# along with this program; if not, write to the Free Software
16
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
17
 
18
18
"""A custom importer and regex compiler which logs time spent."""
19
19
 
20
 
import re
 
20
import sre
21
21
import sys
22
22
import time
23
23
 
26
26
_total_stack = {}
27
27
_info = {}
28
28
_cur_id = 0
29
 
_timer = time.time
30
 
if sys.platform == 'win32':
31
 
    _timer = time.clock
32
29
 
33
30
 
34
31
def stack_add(name, frame_name, frame_lineno, scope_name=None):
41
38
        _total_stack[_parent_stack[-1]].append(this_stack)
42
39
    _total_stack[this_stack] = []
43
40
    _parent_stack.append(this_stack)
44
 
    _info[this_stack] = [len(_parent_stack) - 1, frame_name, frame_lineno,
45
 
                         scope_name]
 
41
    _info[this_stack] = [len(_parent_stack)-1, frame_name, frame_lineno, scope_name]
46
42
 
47
43
    return this_stack
48
44
 
59
55
 
60
56
def log_stack_info(out_file, sorted=True, hide_fast=True):
61
57
    # Find all of the roots with import = 0
62
 
    out_file.write(
63
 
        '%5s %5s %-40s @ %s:%s\n'
64
 
        % ('cum', 'local', 'name', 'file', 'line'))
65
 
    todo = [(value[-1], key) for key, value in _info.items() if value[0] == 0]
 
58
    out_file.write(' cum  inline name\t\t\t\t\t\tframe\n')
 
59
    todo = [(value[-1], key) for key,value in _info.iteritems() if value[0] == 0]
66
60
 
67
61
    if sorted:
68
62
        todo.sort()
86
80
 
87
81
        # indent, cum_time, mod_time, name,
88
82
        # scope_name, frame_name, frame_lineno
89
 
        out_file.write(
90
 
            '%5.1f %5.1f %-40s @ %s:%d\n' % (
91
 
                info[-1] * 1000., mod_time * 1000.,
92
 
                ('+' * info[0] + cur[1]), info[1], info[2]))
 
83
        out_file.write('%5.1f %5.1f %s %-35s\t@ %s:%d\n'
 
84
            % (info[-1]*1000., mod_time*1000., '+'*info[0], 
 
85
               cur[1][:35], info[1], info[2]))
93
86
 
94
87
        if sorted:
95
88
            c_times.sort()
100
93
 
101
94
_real_import = __import__
102
95
 
103
 
def timed_import(name, globals=None, locals=None, fromlist=None, level=0):
 
96
def timed_import(name, globals, locals, fromlist):
104
97
    """Wrap around standard importer to log import time"""
105
 
    # normally there are 4, but if this is called as __import__ eg by
106
 
    # /usr/lib/python2.6/email/__init__.py then there may be only one
107
 
    # parameter
108
 
    # level has different default between Python 2 and 3, but codebase
109
 
    if globals is None:
110
 
        # can't determine the scope name afaics; we could peek up the stack to
111
 
        # see where this is being called from, but it should be a rare case.
112
 
        scope_name = None
 
98
 
 
99
    scope_name = globals.get('__name__', None)
 
100
    if scope_name is None:
 
101
        scope_name = globals.get('__file__', None)
 
102
    if scope_name is None:
 
103
        scope_name = globals.keys()
113
104
    else:
114
 
        scope_name = globals.get('__name__', None)
115
 
        if scope_name is None:
116
 
            scope_name = globals.get('__file__', None)
117
 
        if scope_name is None:
118
 
            scope_name = globals.keys()
119
 
        else:
120
 
            # Trim out paths before breezy
121
 
            loc = scope_name.find('breezy')
122
 
            if loc != -1:
123
 
                scope_name = scope_name[loc:]
 
105
        # Trim out paths before bzrlib
 
106
        loc = scope_name.find('bzrlib')
 
107
        if loc != -1:
 
108
            scope_name = scope_name[loc:]
 
109
        # For stdlib, trim out early paths
 
110
        loc = scope_name.find('python2.4')
 
111
        if loc != -1:
 
112
            scope_name = scope_name[loc:]
124
113
 
125
114
    # Figure out the frame that is doing the importing
126
115
    frame = sys._getframe(1)
142
131
 
143
132
    this = stack_add(extra + name, frame_name, frame_lineno, scope_name)
144
133
 
145
 
    tstart = _timer()
 
134
    tstart = time.time()
146
135
    try:
147
136
        # Do the import
148
 
        return _real_import(name, globals, locals, fromlist, level=level)
 
137
        mod = _real_import(name, globals, locals, fromlist)
149
138
    finally:
150
 
        tload = _timer() - tstart
 
139
        tload = time.time()-tstart
151
140
        stack_finish(this, tload)
152
141
 
153
 
 
154
 
def _repr_regexp(pattern, max_len=30):
155
 
    """Present regexp pattern for logging, truncating if over max_len."""
156
 
    if len(pattern) > max_len:
157
 
        return repr(pattern[:max_len - 3]) + "..."
158
 
    return repr(pattern)
159
 
 
160
 
 
161
 
_real_compile = re._compile
162
 
 
 
142
    return mod
 
143
 
 
144
 
 
145
_real_compile = sre._compile
163
146
 
164
147
def timed_compile(*args, **kwargs):
165
148
    """Log how long it takes to compile a regex"""
175
158
        frame = sys._getframe(5)
176
159
        frame_name = frame.f_globals.get('__name__', '<unknown>')
177
160
    frame_lineno = frame.f_lineno
178
 
    this = stack_add(extra + _repr_regexp(args[0]), frame_name, frame_lineno)
 
161
    this = stack_add(extra+repr(args[0]), frame_name, frame_lineno)
179
162
 
180
 
    tstart = _timer()
 
163
    tstart = time.time()
181
164
    try:
182
165
        # Measure the compile time
183
166
        comp = _real_compile(*args, **kwargs)
184
167
    finally:
185
 
        tcompile = _timer() - tstart
 
168
        tcompile = time.time() - tstart
186
169
        stack_finish(this, tcompile)
187
170
 
188
171
    return comp
191
174
def install():
192
175
    """Install the hooks for measuring import and regex compile time."""
193
176
    __builtins__['__import__'] = timed_import
194
 
    re._compile = timed_compile
 
177
    sre._compile = timed_compile
195
178
 
196
179
 
197
180
def uninstall():
198
181
    """Remove the import and regex compile timing hooks."""
199
182
    __builtins__['__import__'] = _real_import
200
 
    re._compile = _real_compile
 
183
    sre._compile = _real_compile
 
184