~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to profile_imports.py

  • Committer: Alexander Belchenko
  • Date: 2006-07-30 16:43:12 UTC
  • mto: (1711.2.111 jam-integration)
  • mto: This revision was merged to the branch mainline in revision 1906.
  • Revision ID: bialix@ukr.net-20060730164312-b025fd3ff0cee59e
rename  gpl.txt => COPYING.txt

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 sre
20
21
import sys
21
22
import time
22
23
 
23
24
 
24
 
if sys.version_info < (2, 5, 0):
25
 
    import sre
26
 
    re = sre
27
 
else:
28
 
    import re
29
 
 
30
 
 
31
25
_parent_stack = []
32
26
_total_stack = {}
33
27
_info = {}
34
28
_cur_id = 0
35
 
_timer = time.time
36
 
if sys.platform == 'win32':
37
 
    _timer = time.clock
38
29
 
39
30
 
40
31
def stack_add(name, frame_name, frame_lineno, scope_name=None):
64
55
 
65
56
def log_stack_info(out_file, sorted=True, hide_fast=True):
66
57
    # Find all of the roots with import = 0
67
 
    out_file.write('%5s %5s %-40s @ %s:%s\n'
68
 
        % ('cum', 'inline', 'name', 'file', 'line'))
 
58
    out_file.write(' cum  inline name\t\t\t\t\t\tframe\n')
69
59
    todo = [(value[-1], key) for key,value in _info.iteritems() if value[0] == 0]
70
60
 
71
61
    if sorted:
90
80
 
91
81
        # indent, cum_time, mod_time, name,
92
82
        # scope_name, frame_name, frame_lineno
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]))
 
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]))
97
86
 
98
87
        if sorted:
99
88
            c_times.sort()
104
93
 
105
94
_real_import = __import__
106
95
 
107
 
def timed_import(name, globals=None, locals=None, fromlist=None, level=None):
 
96
def timed_import(name, globals, locals, fromlist):
108
97
    """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
113
98
 
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
 
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()
118
104
    else:
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:]
 
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:]
133
113
 
134
114
    # Figure out the frame that is doing the importing
135
115
    frame = sys._getframe(1)
136
116
    frame_name = frame.f_globals.get('__name__', '<unknown>')
137
117
    extra = ''
 
118
    cur_frame = 1
138
119
    if frame_name.endswith('demandload'):
139
120
        # If this was demandloaded, we have 3 frames to ignore
140
 
        extra = '(demandload) '
141
 
        frame = sys._getframe(4)
142
 
        frame_name = frame.f_globals.get('__name__', '<unknown>')
143
 
    elif frame_name.endswith('lazy_import'):
144
 
        # If this was lazily imported, we have 3 frames to ignore
145
 
        extra = '[l] '
146
 
        frame = sys._getframe(4)
147
 
        frame_name = frame.f_globals.get('__name__', '<unknown>')
148
 
    if fromlist:
149
 
        extra += ' [%s]' % (', '.join(map(str, fromlist)),)
 
121
        extra = ' (demandload)'
 
122
        frame = sys._getframe(4)
 
123
        cur_frame = 4
 
124
        frame_name = frame.f_globals.get('__name__', '<unknown>')
150
125
    frame_lineno = frame.f_lineno
151
126
 
152
 
    this = stack_add(extra + name, frame_name, frame_lineno, scope_name)
 
127
    this = stack_add(name+extra, frame_name, frame_lineno, scope_name)
153
128
 
154
 
    tstart = _timer()
 
129
    tstart = time.time()
155
130
    try:
156
131
        # Do the import
157
132
        mod = _real_import(name, globals, locals, fromlist)
158
133
    finally:
159
 
        tload = _timer()-tstart
 
134
        tload = time.time()-tstart
160
135
        stack_finish(this, tload)
161
136
 
162
137
    return mod
163
138
 
164
139
 
165
 
_real_compile = re._compile
166
 
 
 
140
_real_compile = sre._compile
167
141
 
168
142
def timed_compile(*args, **kwargs):
169
143
    """Log how long it takes to compile a regex"""
171
145
    # And who is requesting this?
172
146
    frame = sys._getframe(2)
173
147
    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>')
181
148
    frame_lineno = frame.f_lineno
182
 
    this = stack_add(extra+repr(args[0]), frame_name, frame_lineno)
183
 
 
184
 
    tstart = _timer()
 
149
 
 
150
    this = stack_add(repr(args[0]), frame_name, frame_lineno)
 
151
 
 
152
    tstart = time.time()
185
153
    try:
186
154
        # Measure the compile time
187
155
        comp = _real_compile(*args, **kwargs)
188
156
    finally:
189
 
        tcompile = _timer() - tstart
 
157
        tcompile = time.time() - tstart
190
158
        stack_finish(this, tcompile)
191
159
 
192
160
    return comp
195
163
def install():
196
164
    """Install the hooks for measuring import and regex compile time."""
197
165
    __builtins__['__import__'] = timed_import
198
 
    re._compile = timed_compile
 
166
    sre._compile = timed_compile
199
167
 
200
168
 
201
169
def uninstall():
202
170
    """Remove the import and regex compile timing hooks."""
203
171
    __builtins__['__import__'] = _real_import
204
 
    re._compile = _real_compile
 
172
    sre._compile = _real_compile
205
173