/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: 2010-05-06 11:08:10 UTC
  • mto: This revision was merged to the branch mainline in revision 5223.
  • Revision ID: robertc@robertcollins.net-20100506110810-h3j07fh5gmw54s25
Cleaner matcher matching revised unlocking protocol.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006 by Canonical Ltd
 
1
# Copyright (C) 2006, 2008, 2009, 2010 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
 
18
18
"""A custom importer and regex compiler which logs time spent."""
19
19
 
20
 
import sre
21
20
import sys
22
21
import time
23
22
 
24
23
 
 
24
if sys.version_info < (2, 5, 0):
 
25
    import sre
 
26
    re = sre
 
27
else:
 
28
    import re
 
29
 
 
30
 
25
31
_parent_stack = []
26
32
_total_stack = {}
27
33
_info = {}
28
34
_cur_id = 0
 
35
_timer = time.time
 
36
if sys.platform == 'win32':
 
37
    _timer = time.clock
29
38
 
30
39
 
31
40
def stack_add(name, frame_name, frame_lineno, scope_name=None):
55
64
 
56
65
def log_stack_info(out_file, sorted=True, hide_fast=True):
57
66
    # Find all of the roots with import = 0
58
 
    out_file.write(' cum  inline name\t\t\t\t\t\tframe\n')
 
67
    out_file.write('%5s %5s %-40s @ %s:%s\n'
 
68
        % ('cum', 'inline', 'name', 'file', 'line'))
59
69
    todo = [(value[-1], key) for key,value in _info.iteritems() if value[0] == 0]
60
70
 
61
71
    if sorted:
80
90
 
81
91
        # indent, cum_time, mod_time, name,
82
92
        # scope_name, frame_name, frame_lineno
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][:40], info[1], info[2]))
 
93
        out_file.write('%5.1f %5.1f %-40s @ %s:%d\n'
 
94
            % (info[-1]*1000., mod_time*1000.,
 
95
               ('+'*info[0] + cur[1]),
 
96
               info[1], info[2]))
86
97
 
87
98
        if sorted:
88
99
            c_times.sort()
93
104
 
94
105
_real_import = __import__
95
106
 
96
 
def timed_import(name, globals, locals, fromlist):
 
107
def timed_import(name, globals=None, locals=None, fromlist=None, level=None):
97
108
    """Wrap around standard importer to log import time"""
 
109
    # normally there are 4, but if this is called as __import__ eg by
 
110
    # /usr/lib/python2.6/email/__init__.py then there may be only one
 
111
    # parameter
 
112
    # level is only passed by python2.6
98
113
 
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()
 
114
    if globals is None:
 
115
        # can't determine the scope name afaics; we could peek up the stack to
 
116
        # see where this is being called from, but it should be a rare case.
 
117
        scope_name = None
104
118
    else:
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:]
 
119
        scope_name = globals.get('__name__', None)
 
120
        if scope_name is None:
 
121
            scope_name = globals.get('__file__', None)
 
122
        if scope_name is None:
 
123
            scope_name = globals.keys()
 
124
        else:
 
125
            # Trim out paths before bzrlib
 
126
            loc = scope_name.find('bzrlib')
 
127
            if loc != -1:
 
128
                scope_name = scope_name[loc:]
 
129
            # For stdlib, trim out early paths
 
130
            loc = scope_name.find('python2.4')
 
131
            if loc != -1:
 
132
                scope_name = scope_name[loc:]
113
133
 
114
134
    # Figure out the frame that is doing the importing
115
135
    frame = sys._getframe(1)
117
137
    extra = ''
118
138
    if frame_name.endswith('demandload'):
119
139
        # If this was demandloaded, we have 3 frames to ignore
120
 
        extra = ' (demandload)'
 
140
        extra = '(demandload) '
121
141
        frame = sys._getframe(4)
122
142
        frame_name = frame.f_globals.get('__name__', '<unknown>')
123
143
    elif frame_name.endswith('lazy_import'):
124
144
        # If this was lazily imported, we have 3 frames to ignore
125
 
        extra = ' (lazy)'
 
145
        extra = '[l] '
126
146
        frame = sys._getframe(4)
127
147
        frame_name = frame.f_globals.get('__name__', '<unknown>')
 
148
    if fromlist:
 
149
        extra += ' [%s]' % (', '.join(map(str, fromlist)),)
128
150
    frame_lineno = frame.f_lineno
129
151
 
130
 
    this = stack_add(name+extra, frame_name, frame_lineno, scope_name)
 
152
    this = stack_add(extra + name, frame_name, frame_lineno, scope_name)
131
153
 
132
 
    tstart = time.time()
 
154
    tstart = _timer()
133
155
    try:
134
156
        # Do the import
135
157
        mod = _real_import(name, globals, locals, fromlist)
136
158
    finally:
137
 
        tload = time.time()-tstart
 
159
        tload = _timer()-tstart
138
160
        stack_finish(this, tload)
139
161
 
140
162
    return mod
141
163
 
142
164
 
143
 
_real_compile = sre._compile
 
165
_real_compile = re._compile
 
166
 
144
167
 
145
168
def timed_compile(*args, **kwargs):
146
169
    """Log how long it takes to compile a regex"""
148
171
    # And who is requesting this?
149
172
    frame = sys._getframe(2)
150
173
    frame_name = frame.f_globals.get('__name__', '<unknown>')
 
174
 
 
175
    extra = ''
 
176
    if frame_name.endswith('lazy_regex'):
 
177
        # If this was lazily compiled, we have 3 more frames to ignore
 
178
        extra = '[l] '
 
179
        frame = sys._getframe(5)
 
180
        frame_name = frame.f_globals.get('__name__', '<unknown>')
151
181
    frame_lineno = frame.f_lineno
152
 
 
153
 
    this = stack_add(repr(args[0]), frame_name, frame_lineno)
154
 
 
155
 
    tstart = time.time()
 
182
    this = stack_add(extra+repr(args[0]), frame_name, frame_lineno)
 
183
 
 
184
    tstart = _timer()
156
185
    try:
157
186
        # Measure the compile time
158
187
        comp = _real_compile(*args, **kwargs)
159
188
    finally:
160
 
        tcompile = time.time() - tstart
 
189
        tcompile = _timer() - tstart
161
190
        stack_finish(this, tcompile)
162
191
 
163
192
    return comp
166
195
def install():
167
196
    """Install the hooks for measuring import and regex compile time."""
168
197
    __builtins__['__import__'] = timed_import
169
 
    sre._compile = timed_compile
 
198
    re._compile = timed_compile
170
199
 
171
200
 
172
201
def uninstall():
173
202
    """Remove the import and regex compile timing hooks."""
174
203
    __builtins__['__import__'] = _real_import
175
 
    sre._compile = _real_compile
 
204
    re._compile = _real_compile
176
205