for arco stuff
[The-Artvertiser.git] / artvertiser / FProfiler / FProfiler.h
blob12fdeea2d7c996eed65f3f58be5e917b3c422814
1 /*
2 * FProfiler.h
3 * F
5 * Created by damian on 25/5/08.
6 * Copyright 2008 frey damian@frey.co.nz. All rights reserved.
8 */
10 #ifndef __PROFILER_H
11 #define __PROFILER_H
14 /** FProfiler
16 A thread-safe profiler. On call to Display(), displays result by thread.
18 To use, #include "FProfiler.h", and globally #define PROFILE. Then, use
19 the following macros to profile parts of code:
21 * PROFILE_SECTION_PUSH( label ) and PROFILE_SECTION_POP()
23 Profile code between these calls, storing results in a tree.
24 For example:
26 .. unprofiled preprocessing
27 PROFILE_SECTION_PUSH( "partial section" );
28 .. code to be profiled
29 PROFILE_SECTION_POP();
30 .. unprofiled postprocessing
32 Or for nested output:
34 PROFILE_SECTION_PUSH( "two-step process" );
35 .. preprocessing code
36 PROFILE_SECTION_PUSH( "step 1" );
37 .. step 1 code
38 PROFILE_SECTION_POP();
39 PROFILE_SECTION_PUSH( "step 2" );
40 .. step 2 code
41 PROFILE_SECTION_POP();
42 PROFILE_SECTION_POP();
44 will yield the output
45 - two-step process <total time for steps 1 + 2 + preprocessing> ...
46 - - step 1 <time for step 1> ...
47 - - step 2 <time for step 2> ...
49 NOTE: all labels at a given level in the tree must be unique.
51 * PROFILE_THIS_FUNCTION()
53 Wraps the current function in a pair of
54 PROFILE_SECTION_PUSH( function_name ) and PROFILE_SECTION_POP calls.
56 * PROFILE_THIS_BLOCK( label )
58 Wraps the current block (the code between the current level { and })
59 in a pair of PROFILE_SECTION_PUSH( label ) and PROFILE_SECTION_POP
60 calls.
62 eg:
64 if ( test_condition )
66 PROFILE_THIS_BLOCK( "test passed" );
67 // code to run on test condition
71 To display profile results, call FProfiler::Display();
73 @author Damian
78 /// macros
79 #ifdef PROFILE
80 #define PROFILE_SECTION_PUSH( label ) FProfiler::SectionPush( label );
81 #define PROFILE_SECTION_POP() FProfiler::SectionPop();
82 #define PROFILE_THIS_FUNCTION() volatile FFunctionProfiler __function_profiler_object__( __FUNCTION__ );
83 #define PROFILE_THIS_BLOCK( label ) volatile FFunctionProfiler __section_profiler_object__##__LINE__( label );
84 #warning Profiling with FProfiler enabled
85 #else
86 #define PROFILE_SECTION_PUSH( label ) ;
87 #define PROFILE_SECTION_POP() ;
88 #define PROFILE_THIS_FUNCTION() ;
89 #define PROFILE_THIS_BLOCK( label );
90 //#warning Profiling with FProfiler disabled
91 #endif
94 #include "FSemaphore.h"
95 #include "FTime.h"
96 #include "FThread.h"
97 #include <map>
98 #include <string>
99 #include <vector>
102 class FProfileSection;
104 class FProfileContext
106 public:
107 FThreadContext thread_context;
108 FProfileSection* toplevel;
109 FProfileSection* current;
111 FProfileContext() { toplevel = NULL; }
112 ~FProfileContext();
116 class FProfiler
118 public:
119 /// clear the database and restart profiling
120 static void Clear();
122 /// start a section
123 static void SectionPush( const std::string& name = "unlabelled section" );
124 /// end a section
125 static void SectionPop();
127 /// return a pointer to the context for the current thread
128 static FProfileContext* GetContext();
130 /// show profiles recorded. SORT_BY defines sort order.
131 typedef enum _SORT_BY { SORT_EXECUTION, SORT_TIME } SORT_BY;
132 static void Display( SORT_BY sort = SORT_TIME );
134 private:
136 // for efficiency: avoid re-allocating
137 static FTime end_time;
140 typedef std::vector<FProfileContext*> FProfileContexts;
141 static FProfileContexts contexts;
143 static FSemaphore lock;
146 // one section
147 class FProfileSection {
148 public:
149 FProfileSection();
150 ~FProfileSection();
152 void Display( const std::string& prefix, FProfiler::SORT_BY sort_by );
154 int call_count;
155 double avg_time;
156 int exec_order_id;
157 static int EXEC_ORDER_ID;
159 FTime timer;
160 // LARGE_INTEGER start_time;
162 FProfileSection* parent;
163 std::string name;
165 // map of sections
166 typedef std::map<const std::string, FProfileSection* > FProfileSections;
168 // don't try this at home
169 /*struct less_than_comparator : public std::binary_function<const ProfileSection*,const ProfileSection*,bool>
171 result_type operator() ( first_argument_type a, second_argument_type b )
173 return ( a->avg_time * a->call_count < b->avg_time*b->call_count );
175 };*/
176 FProfileSections children;
184 /** FFunctionProfiler
186 convenience class. designed to be used as a volatile instance, within a function/block.
190 class FFunctionProfiler
192 public:
193 FFunctionProfiler( const char* function_name )
194 { FProfiler::SectionPush(function_name); }
195 ~FFunctionProfiler()
196 { FProfiler::SectionPop(); }
201 #endif