Introduction
This is a profiler for Visual C++ 2003.
I needed a profiler for C++ (Visual Studio 2003) to check out where the bottleneck is in some of my projects. No bells and whistles. The profiler should be very easy to use. And it should be able to count the execution time instead of/on top of the total time elapsed for each function (explained later).
On the other hand, I don't need an ultra-accurate timer and a reasonable overhead by the profiling code is acceptable. My reason is: I know optimization is "evil" -- well, over-optimization perhaps. So I just want to spot out the stupid functions which look innocent but use up 30% of the execution time and can easily be reduced to 5%.
I definitely don’t need a fancy UI with a CListCtrl
. I’d prefer a CSV output so that I can view and analyze the results in Excel.
And here it is.
The Execution Time
The timing of functions is well-explained by Hernán Di Pietro’s CProfile - A simple class to do code profiling and tracing. I will say a bit about recording the execution time of functions here.
Consider functions Foo()
and Bar()
. Foo()
calls Bar()
. If I recorded the time at the entry and exit points Foo()
and calculated the duration, I would include the execution time of Bar()
s in Foo()
s. I want to know what time exactly does and only does Foo()
take. So on top of recording the entry and exit time, I also have an offset amount. This amount is deducted by every profiled function call.
I use a stack to find out the matching entry and exit records of each function call. The total elapsed time and the execution time (offset by duration of function calls in the function) are then calculated. Each duration is put in a CMap
with keys of the function names. Note that since all function names by the directive __FUNCTION__
are constant strings. There is no need to copy/delete the char pointers.
Usage
Just add profile.cpp and profile.h in your project. Include “profile.h” and put the macro “PP” at the very beginning of each function to be profiled. At the end of your program, call CProfiler::ExportProf()
. A CSV file will be saved under the application directory. The demo project is commented and should be very straight-forward. In the demo project, functions in the class CProfTest
are to be profiled.
This is the first time I have posted an article here. I just hope I haven’t broken too many rules. Any criticism and/or feedback is equally welcome.
Update Nov 30, 2006
Thanks to eTurtle and yarp's posts.
To profile a multithreading program. I add a map of stacks to keep track of the entry/exit times for each separate thread. So the offset mentioned above won't affect other threads. I added a CCriticalSection
to protect the operations of the static collection. I am not sure whether this is necessary. And I am not sure whether there are some cases there I overlooked. But so far it seems it works OK for my simple multithreading test case. Of course this is supposed to be a "quick 'n dirty" trick. ;)
Please let me know should there be any problem.
Also fixed some minor bugs and added some more comments, tidied up the code a bit. Please download the updated version when it's ready.
I add the "locale" support for the CSV and fixed the date format as pointed by eTurtle. I thought I could think straight when I prepared this article and the project -- after half a dozen beers...
後會有期。