Merge lp://staging/~gary/launchpad/profiler into lp://staging/launchpad
Status: | Merged |
---|---|
Approved by: | Gary Poster |
Approved revision: | no longer in the source branch. |
Merged at revision: | 13672 |
Proposed branch: | lp://staging/~gary/launchpad/profiler |
Merge into: | lp://staging/launchpad |
Diff against target: |
1007 lines (+385/-209) 4 files modified
lib/lp/services/profile/__init__.py (+15/-2) lib/lp/services/profile/profile.pt (+45/-14) lib/lp/services/profile/profile.py (+162/-82) lib/lp/services/profile/tests.py (+163/-111) |
To merge this branch: | bzr merge lp://staging/~gary/launchpad/profiler |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Robert Collins (community) | Needs Information | ||
Gavin Panella (community) | Approve | ||
Review via email:
|
Commit message
[r=allenap][bug=824632] Add ability to profile parts of a request, aggregated if they repeat.
Description of the change
In the course of trying to figure out how best to fix bug 724025 (a timeout bug involving Python rather than SQL) I made more tweaks to the ++profile++ tool. These changes do three things.
1) Make it possible to insert profile requests within the code, using the "profiling" context manager or the "start"/"stop" calls. Multiple calls within a request are aggregated.
2) Make it possible to ask for both callgrind and pstats simultaneously. This was not that important to me, but fell out of the refactoring I was doing.
3) Make the in-browser "show" functionality use the pstats rendering, because I liked it better (it gave aggregate time, for one thing).
Along the way, I simplified some tests by abstracting out assertion helpers, and I removed some hacks to use the BzrProfiler itself and simplified the code by using only the Bzr Stats class when we need to write callgrind files.
lint is happy except for its usual confusion with profile.pt.
./lib/lp/
6: junk after document element
I'm sorry for the extra size of the branch.
Thank you!
Gary
I'd never played with this before, and now I'm very glad I have.
[1]
+ self.__ class__ .profiler_ lock.acquire( True) # Blocks.
Is there a reason you chose to refer to profiler_lock via
self.__class__ rather than self?
[2]
+ actions = getattr(_profilers, 'actions', None)
+ profiler = getattr(_profilers, 'profiler', None)
Btw, instead of lots of guard code around using _profilers, it's
possible to subclass and get a ordinary looking object:
class Profilers( threading. local):
def __init__(self):
self. profiling = False
self. actions = None
self. profiler = None
self. profiling = False
# ...
_profilers = Profilers()
__init__() gets called once for each new thread the instance is used
in, and the class can have methods and properties as usual. Might be
interesting.
Fwiw, I verified this to myself with http:// paste.ubuntu. com/663456/