--- ZopeProfiler.py~ 2007-06-26 10:43:25.000000000 +0200A few years ago we had no other option than digging in the raw stats as they come from Stats.sort_stats().print_stats(). Since then there is a new tool: Gprof2dot. The author also made something more than handy: xdot.py.
+++ ZopeProfiler.py 2008-12-22 18:02:26.000000000 +0100
@@ -393,10 +393,10 @@
# Five broke 'getPhysicalPath' for its view classes -- work around
try: p= gP()
except:
- _log.error("calling 'getPhysicalPath' failed for %r", s,
- exc_info=sys.exc_info()
- )
- return
+ # _log.error("calling 'getPhysicalPath' failed for %r", s,
+ # exc_info=sys.exc_info()
+ # )
+ return ('?', _Empty, fn)
if type(p) is StringType: fi= p
else: fi= '/'.join(p)
return (fi,_Empty,fn)
Now just add a little bash function:
$ function build_dot() { ./gprof2dot.py -f pstats -o $(basename $1 .pstats).dot $1; }Then my workflow for profiling some pages could be faster and easier:- Profile a page, and save "some_page.pstats"
- run "build_dot some_page.pstats"
- run "./xdot.py some_page.dot"
- visit the graph
The mouse wheel allows to zoom in/out, holding left-click and moving the mouse will move the graph. It's quite easy to quickly find some hotspots, sometimes they will appear very obviously:
Another interesting hotspot (in plone 2.5): for some pages up to 15% of the time in spent in... getAllowedTypes (just 1 call - nearly 11% in pythonproducts.py __bobo_traverse__).
5 comments:
You might want to check out factoryhack and contentmenu.
http://www.jarn.com/blog/plone-2-5-performance
I had a product that was spending a lot of time copying schemas. I realized later that I had an Archetypes class that was modifying schema on the fly (using ISchema) by copying the existing schema and adding some fields. Because the class' Schema was looked up multiple times in edit forms, this slowed the web site down to a crawl. Now I create a variable that stores the modified schema once, which is looked up on the fly.
I'm sharing this in case it might be related to your profiling results!
@tesdal: thank you for reminding me theses posts. The 2 products are really interesting!
@george: Your method is effective, but I would rather use cache decorator on the Schema method, just like I mentioned: they are doing the work you do manually, and are reusable if you have to do this more than 1 time (= cache another function result). So, why writing code when a library has already what you want? The point is to choose the right one (global cache, per object, user, arguments, request...?). Furthermore, plone.memoize 1.0.4 may be used with zope 2.9; or just use the ones from CMFPlone 2.5.
The bug you notice is always here in ZopeProfiler 2.0.
It seems to be a collateral damage with PDBDebugMode.
Wow, this is so useful. Thanks a lot for writing this down, Bertand.
Post a Comment