~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to profile_imports.py

  • Committer: John Arbash Meinel
  • Date: 2006-06-18 02:05:12 UTC
  • mto: This revision was merged to the branch mainline in revision 1794.
  • Revision ID: john@arbash-meinel.com-20060618020512-fda8734b5131f469
Move the custom importers into a separate module

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2006 by Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
"""A custom importer and regex compiler which logs time."""
 
18
 
 
19
import os
 
20
import sys
 
21
import time
 
22
import sre
 
23
 
 
24
 
 
25
_import_logfile = sys.stderr
 
26
_compile_logfile = sys.stderr
 
27
 
 
28
_real_import = __import__
 
29
 
 
30
def _custom_import(name, globals, locals, fromlist):
 
31
    """Wrap around standard importer to log import time"""
 
32
    if _import_logfile is None:
 
33
        return _real_import(name, globals, locals, fromlist)
 
34
 
 
35
    scope_name = globals.get('__name__', None)
 
36
    if scope_name is None:
 
37
        scope_name = globals.get('__file__', None)
 
38
    if scope_name is None:
 
39
        scope_name = globals.keys()
 
40
    else:
 
41
        # Trim out paths before bzrlib
 
42
        loc = scope_name.find('bzrlib')
 
43
        if loc != -1:
 
44
            scope_name = scope_name[loc:]
 
45
        # For stdlib, trim out early paths
 
46
        loc = scope_name.find('python2.4')
 
47
        if loc != -1:
 
48
            scope_name = scope_name[loc:]
 
49
                
 
50
    # Do the import
 
51
    tstart = time.time()
 
52
    mod = _real_import(name, globals, locals, fromlist)
 
53
    tload = time.time()-tstart
 
54
 
 
55
    # Figure out the frame that is doing the importing
 
56
    frame = sys._getframe(1)
 
57
    frame_name = frame.f_globals.get('__name__', '<unknown>')
 
58
    extra = ''
 
59
    cur_frame = 1
 
60
    if frame_name.endswith('demandload'):
 
61
        # If this was demandloaded, we have 3 frames to ignore
 
62
        extra = ' (demandload)'
 
63
        frame = sys._getframe(4)
 
64
        cur_frame = 4
 
65
        frame_name = frame.f_globals.get('__name__', '<unknown>')
 
66
    frame_lineno = frame.f_lineno
 
67
 
 
68
    # Log the import
 
69
    _import_logfile.write('%3.0fms %-24s\tfor %-24s\t@ %s:%d%s\n' 
 
70
        % ((time.time()-tstart)*1000, name, scope_name,
 
71
            frame_name, frame_lineno, extra))
 
72
 
 
73
    # If the import took a long time, log the stack that generated
 
74
    # this import. Especially necessary for demandloaded code
 
75
    if tload > 0.01:
 
76
        stack = []
 
77
        for fnum in range(cur_frame+1, cur_frame+10):
 
78
            try:
 
79
                f = sys._getframe(fnum)
 
80
            except ValueError:
 
81
                break
 
82
            stack.append('%s:%i' 
 
83
                    % (f.f_globals.get('__name__', '<unknown>'),
 
84
                        f.f_lineno)
 
85
                    )
 
86
        if stack:
 
87
            _import_logfile.write('\t' + ' '.join(stack) + '\n')
 
88
    return mod
 
89
 
 
90
 
 
91
_real_compile = sre._compile
 
92
 
 
93
def _custom_compile(*args, **kwargs):
 
94
    """Log how long it takes to compile a regex"""
 
95
    if _compile_logfile is None:
 
96
        return _real_compile(*args, **kwargs)
 
97
 
 
98
    # Measure the compile time
 
99
    tstart = time.time()
 
100
    comp = _real_compile(*args, **kwargs)
 
101
    
 
102
    # And who is requesting this?
 
103
    frame = sys._getframe(2)
 
104
    frame_name = frame.f_globals.get('__name__', '<unknown>')
 
105
    frame_lineno = frame.f_lineno
 
106
    _compile_logfile.write('%3.0fms %-40r\t@ %s:%d\n'
 
107
        % ((time.time()-tstart)*1000, args[0][:40], 
 
108
            frame_name, frame_lineno))
 
109
    return comp
 
110
 
 
111
__builtins__.__import__ = _custom_import
 
112
sre._compile = _custom_compile