At work, a project I have been involved in was a bit slow, and we have had the task of profiling it to see why. We started doing the usual ad hoc profiling (now=time.time() / do something / print "something took " time.time()-now), but that was rather tedious.
The project itself has one object class which implements a lot of the data model and operations. So I decided to write a proxy/wrapper class which would wrap any class, time its method calls and output statistics. This soon gained the ability to keep track of which method was calling which other methods, and what was taking up most of the calling time, and to output it in nice tree-formatted dumps.
Anyway, for those who code in Python and might find something like this useful, here it is. There's a Cheese Shop page on it here.