1 <?php
2 3 4 5 6
7
8
9
10 11 12 13 14 15
16 class Profiler {
17 var $description;
18 var $startTime;
19 var $endTime;
20 var $initTime;
21 var $cur_timer;
22 var $stack;
23 var $trail;
24 var $trace;
25 var $count;
26 var $running;
27
28 protected static $inst;
29
30 31 32
33 function Profiler( $output_enabled=false, $trace_enabled=false)
34 {
35 $this->description = array();
36 $this->startTime = array();
37 $this->endTime = array();
38 $this->initTime = 0;
39 $this->cur_timer = "";
40 $this->stack = array();
41 $this->trail = "";
42 $this->trace = "";
43 $this->count = array();
44 $this->running = array();
45 $this->initTime = $this->getMicroTime();
46 $this->output_enabled = $output_enabled;
47 $this->trace_enabled = $trace_enabled;
48 $this->startTimer('unprofiled');
49 }
50
51
52
53 static function init() {
54 if(!self::$inst) self::$inst = new Profiler(true,true);
55 }
56
57 static function mark($name, $level2 = "", $desc = "") {
58 if($level2 && $_GET['debug_profile'] > 1) $name .= " $level2";
59
60 if(!self::$inst) self::$inst = new Profiler(true,true);
61
62 self::$inst->startTimer($name, $desc);
63 }
64 static function unmark($name, $level2 = "", $desc = "") {
65 if($level2 && $_GET['debug_profile'] > 1) $name .= " $level2";
66
67 if(!self::$inst) self::$inst = new Profiler(true,true);
68
69 self::$inst->stopTimer($name, $desc);
70 }
71 static function show($showTrace = false) {
72 if(!self::$inst) self::$inst = new Profiler(true,true);
73
74 echo "<div style=\"position: absolute; z-index: 100000; top: 20px; left: 20px; background-color: white; padding: 20px; border: 1px #AAA solid; height: 80%; overflow: auto;\">";
75 echo "<p><a href=\"#\" onclick=\"this.parentNode.parentNode.style.display = 'none'; return false;\">(Click to close)</a></p>";
76 self::$inst->printTimers();
77 if($showTrace) self::$inst->printTrace();
78 echo "</div>";
79 }
80
81 82 83 84 85 86
87 function startTimer($name, $desc="" ){
88 $this->trace.="start $name\n";
89 $n=array_push( $this->stack, $this->cur_timer );
90 $this->__suspendTimer( $this->stack[$n-1] );
91 $this->startTime[$name] = $this->getMicroTime();
92 $this->cur_timer=$name;
93 $this->description[$name] = $desc;
94 if (!array_key_exists($name,$this->count))
95 $this->count[$name] = 1;
96 else
97 $this->count[$name]++;
98 }
99
100 101 102 103 104
105 function stopTimer($name){
106 $this->trace.="stop $name\n";
107 $this->endTime[$name] = $this->getMicroTime();
108 if (!array_key_exists($name, $this->running))
109 $this->running[$name] = $this->elapsedTime($name);
110 else
111 $this->running[$name] += $this->elapsedTime($name);
112 $this->cur_timer=array_pop($this->stack);
113 $this->__resumeTimer($this->cur_timer);
114 }
115
116 117 118 119
120 function elapsedTime($name){
121
122 if (!array_key_exists($name,$this->startTime))
123 return 0;
124
125 if(array_key_exists($name,$this->endTime)){
126 return ($this->endTime[$name] - $this->startTime[$name]);
127 } else {
128 $now=$this->getMicroTime();
129 return ($now - $this->startTime[$name]);
130 }
131 }
132
133 134 135 136
137 function elapsedOverall(){
138 $oaTime = $this->getMicroTime() - $this->initTime;
139 return($oaTime);
140 }
141
142 143 144 145
146 function printTimers($enabled=false)
147 {
148 if($this->output_enabled||$enabled){
149 $TimedTotal = 0;
150 $tot_perc = 0;
151 ksort($this->description);
152 print("<pre>\n");
153 $oaTime = $this->getMicroTime() - $this->initTime;
154 echo"============================================================================\n";
155 echo " PROFILER OUTPUT\n";
156 echo"============================================================================\n";
157 print( "Calls Time Routine\n");
158 echo"-----------------------------------------------------------------------------\n";
159 while (list ($key, $val) = each ($this->description)) {
160 $t = $this->elapsedTime($key);
161 $total = $this->running[$key];
162 $count = $this->count[$key];
163 $TimedTotal += $total;
164 $perc = ($total/$oaTime)*100;
165 $tot_perc+=$perc;
166
167 $lines[ sprintf( "%3d %3.4f ms (%3.2f %%) %s\n", $count, $total*1000, $perc, $key) ] = $total;
168 }
169 arsort($lines);
170 foreach($lines as $line => $total) {
171 echo $line;
172 }
173
174 echo "\n";
175
176 $missed=$oaTime-$TimedTotal;
177 $perc = ($missed/$oaTime)*100;
178 $tot_perc+=$perc;
179
180 printf( " %3.4f ms (%3.2f %%) %s\n", $missed*1000,$perc, "Missed");
181
182 echo"============================================================================\n";
183
184 printf( " %3.4f ms (%3.2f %%) %s\n", $oaTime*1000,$tot_perc, "OVERALL TIME");
185
186 echo"============================================================================\n";
187
188 print("</pre>");
189 }
190 }
191
192 function printTrace( $enabled=false )
193 {
194 if($this->trace_enabled||$enabled){
195 print("<pre>");
196 print("Trace\n$this->trace\n\n");
197 print("</pre>");
198 }
199 }
200
201
202
203 204 205 206
207 function getMicroTime(){
208 $tmp=explode(' ', microtime());
209 $rt=$tmp[0]+$tmp[1];
210 return $rt;
211 }
212
213 214 215 216
217 function __resumeTimer($name){
218 $this->trace.="resume $name\n";
219 $this->startTime[$name] = $this->getMicroTime();
220 }
221
222 223 224 225
226 function __suspendTimer($name){
227 $this->trace.="suspend $name\n";
228 $this->endTime[$name] = $this->getMicroTime();
229 if (!array_key_exists($name, $this->running))
230 $this->running[$name] = $this->elapsedTime($name);
231 else
232 $this->running[$name] += $this->elapsedTime($name);
233 }
234 }
235 ?>
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the
Silverstripe Forums to ask development related questions.
-