My favorites | Sign in
Project Home Wiki Issues Source
Checkout   Browse   Changes    
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
<?php
// vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
/**
* Container for {@link tgif_benchmark_timer}
*
* @package tgiframework
* @subpackage debugging
* @copyright 2009 terry chay
* @license GNU Lesser General Public License <http://www.gnu.org/licenses/lgpl.html>
*/
// {{{ tgif_benchmark_timer
// docs {{{
/**
* Similar to PEAR {@link Benchmark_Timer}, except without the userspace
* profiling and the named laptiming facilities.
*
* Unlike Benchmark_Timer, this can also use {@link getrusage()} to get real
* system ticks on the process.
*
* @package tgiframework
* @subpackage debugging
* @author terry chay <tychay@php.net> refactored from {@link tgif_diagnostics}
*/
// }}}
class tgif_benchmark_timer
{
// PRIVATE INTERNALS
// {{{ - $_trackRusage
/**
* If set to true, this will track resource usage via
* {@link http://php.net/getrusage getrusage()}
* @var boolean
*/
private $_trackRusage;
// }}}
// {{{ - $_startTime
/**
* Stores the start time in microtime(false) format.
* @var string
*/
private $_startTime;
// }}}
// {{{ - $_stopTime
/**
* Stores the stop time in microtime(false) format.
* @var string
*/
private $_stopTime;
// }}}
// {{{ - $_startRusage
/**
* Stores the rusage stats at the start of the timer
* @var array
*/
private $_startRusage;
// }}}
// {{{ - $_stopRusage
/**
* Stores the rusage stats at the end of the timer
* @var array
*/
private $_stopRusage;
// }}}
// {{{ - $_summary
/**
* Stores the time differences and the like
* @var array
*/
private $_summary = array();
// }}}
// RESERVED METHODS
// {{{- __construct($shouldStart[$trackRSuage])
/**
* Constructor for object.
*
* If you want trackRusage to work in windows, install cygwin.
*
* @param boolean $shouldStart if true then it will start the timer
* @param boolean $trackRusage if true then it will track the resource usage
* also
* automatically
*/
public function __construct($shouldStart,$trackRusage=false)
{
$this->_trackRusage = $trackRusage;
if ($shouldStart) { $this->start(); }
}
// }}}
// TIMERS
// {{{ - start()
/**
* Start the timer.
*/
function start()
{
$this->_startTime = microtime();
if ($this->_trackRusage) {
$this->_startRusage = getrusage();
}
}
// }}}
// {{{ - stop([$sumTotal])
/**
* Stops the timer.
*
* Moved the math function around the timers to make the timers slightly
* more accurate. Also improved the adding function to not lose precision.
*
* @param boolean $sumTotal should summary keep a running total?
*/
function stop($sumTotal=false)
{
// stop timers {{{
if ($this->_trackRusage) {
$this->_stopRusage = getrusage();
}
$this->_stopTime = microtime();
// }}}
// compute time taken {{{
$time = self::microtime_subtract($this->_stopTime, $this->_startTime);
if ($this->_trackRusage) {
$utime = self::microtime_subtract(self::rusage_to_microtime($this->_stopRusage,'ru_utime.tv'),self::rusage_to_microtime($this->_startRusage,'ru_utime.tv'));
$stime = self::microtime_subtract(self::rusage_to_microtime($this->_stopRusage,'ru_stime.tv'),self::rusage_to_microtime($this->_startRusage,'ru_stime.tv'));
$rtime = self::bc_add($utime,$stime);
}
// }}}
// add to total {{{
if (!$sumTotal && !$this->_trackRusage) {
$this->_summary = array('time' => $time);
} elseif (!$sumTotal) { //rusage
$this->_summary = array(
'time' => $time,
'utime' => $utime,
'stime' => $stime,
'rtime' => $rtime,
);
} else {
// zero out array {{{
if (empty($this->_summary) && !$this->_trackRusage) {
$this->_summary = array('time' => '0.0');
} else {
$this->_summary = array(
'time' => '0.0',
'utime' => '0.0',
'stime' => '0.0',
'rtime' => '0.0',
);
}
// }}}
$this->_summary['time'] = self::bc_add($this->_summary['time'],$time);
if ($this->_trackRusage) {
$this->_summary['utime'] = self::bc_add($this->_summary['utime'],$utime);
$this->_summary['stime'] = self::bc_add($this->_summary['stime'],$stime);
$this->_summary['rtime'] = self::bc_add($this->_summary['rtime'],$rtime);
}
}
// }}}
}
// }}}
// ACCESSORS
// {{{ - __get($name)
/**
* Allow you to get values
* @return mixed if false you didn't record that value
*/
function __get($name)
{
switch (strtolower($name)) {
case 'starttime':
case 'begintime':
return self::microtime_float($this->_startTime);
case 'stoptime':
case 'endtime':
return self::microtime_float($this->_stopTime);
case 'timetaken':
case 'timedifference':
return $this->_summary['time'];
case 'rtimetaken':
return $this->_summary['rtime'];
case 'stimetaken':
return $this->_summary['stime'];
case 'utimetaken':
return $this->_summary['utime'];
}
trigger_error(sprintf('Unknown property %s',$name), E_USER_WARNING);
}
// }}}
// {{{ - __set($name,$value)
/**
* Allow you to change the values
*/
function __set($name, $value)
{
switch (strtolower($name)) {
case 'starttime':
case 'begintime':
$this->_startTime = $value;
return;
case 'startrusage':
case 'beginusage':
$this->_startRusage = $value;
return;
}
trigger_error(sprintf('Unknown property %s',$name), E_USER_WARNING);
}
// }}}
// STATIC METHODS
// {{{ + rusage_to_microtime($rusageArray,$indexName[,$asFloat])
/**
* Turns rusage time results into microtime format
*
* @param array $rusageArray the Rusage time
* @param string $indexName e.g. 'ru_utime.tv'
* @param boolean $asFloat If true, it ends up looking like the time was
* passed through {@link microtime_float()}.
* @return string the time in microtime format
* float)
*/
static function rusage_to_microtime($rusageArray, $indexName, $asFloat=false)
{
if ($asFloat) {
return $rusageArray[$indexName.'_sec'] . '.' . $rusageArray[$indexName.'_usec'];
} else {
return '0.'.$rusageArray[$indexName.'_usec'] . ' ' . $rusageArray[$indexName.'_sec'];
}
}
// }}}
// {{{ + bc_add($time1,$time2)
/**
* Add two precision strings
*
* @param string $time1 addend in bc format
* @param string $time2 addend in bc format
* @return string the sum of times seconds (can be interpreted as a
* float)
*/
static function bc_add($time1,$time2)
{
// use bc math to do subtraction if available {{{
if (extension_loaded('bcmath')) {
return bcadd($time1, $time2, 6);
}
// }}}
if (!$time1) { $time1 = '0.0'; }
if (!$time2) { $time2 = '0.0'; }
if (!strpos($time1,'.')) { $time1 .= '.0'; }
if (!strpos($time2,'.')) { $time2 .= '.0'; }
list($end_usec, $end_sec) = explode('.', $time1);
list($start_usec, $start_sec) = explode('.',$time2);
$usec = ('0.'.$end_usec) + ('0.'+$start_usec);
$carry = ($usec > 1) ? 1 : 0;
$sec = $end_sec + $start_sec + $carry;
return $sec.substr($usec,1);
}
// }}}
// {{{ + bc_sub($time1,$time2)
/**
* Subtracts two precision strings
*
* Enhanced to use bcmath if available.
*
* @param string $time1 end time in bc format
* @param string $time2 start time in bc format
* @return string the time difference in seconds (can be interpreted as a
* float)
*/
static function bc_sub($time1,$time2)
{
// use bc math to do subtraction if available {{{
if (extension_loaded('bcmath')) {
return bcsub($time1, $time2, 6);
}
// }}}
if (!$time1) { $time1 = '0.0'; }
if (!$time2) { $time2 = '0.0'; }
if (!strpos($time1,'.')) { $time1 .= '.0'; }
if (!strpos($time2,'.')) { $time2 .= '.0'; }
list($end_usec, $end_sec) = explode('.', $time1);
list($start_usec, $start_sec) = explode('.',$time2);
$usec = ('0.'.$end_usec) - ('0.'.$start_usec);
$carry = 0;
if ($usec < 0) {
$usec = 1 + $usec;
$carry = 1;
}
$sec = $end_sec - $start_sec - $carry;
//return $sec.substr($usec,1).' = '.$time1.' - '.$time2;
return $sec.substr($usec,1);
}
// }}}
// {{{ + microtime_subtract($time1,$time2)
/**
* Subtracts two microtime strings
*
* Enhanced to use bcmath if available.
*
* @param string $time1 end time in microtime format
* @param string $time2 start time in microtime format
* @return string the time difference in seconds (can be interpreted as a
* float)
*/
static function microtime_subtract($time1,$time2)
{
// use bc math to do subtraction if available {{{
if (extension_loaded('bcmath')) {
return bcsub(self::microtime_float($time1), self::microtime_float($time2), 6);
}
// }}}
list($end_usec, $end_sec) = explode(' ', $time1);
list($start_usec, $start_sec) = explode(' ',$time2);
$usec = $end_usec - $start_usec;
if ($usec == 0) { $usec = '0.0'; } //edge case: zero seconds (microtime not really a microtime)
$carry = 0;
if ($usec < 0) {
$usec = 1 + $usec;
$carry = 1;
}
$sec = $end_sec - $start_sec - $carry;
//return $sec.substr($usec,1).' = '.$time1.' - '.$time2;
return $sec.substr($usec,1);
}
// }}}
// {{{ + microtime_float([$microtime])
/**
* Emulates microtime(true) for PHP < 4
* @param $microtime string the time to convert. If false, then it will
* assume you want this instant.
* @return string a GMP formatted microtime string
*/
static function microtime_float($microtime=false)
{
if ($microtime === false) {
$microtime = microtime();
}
list($usec, $sec) = explode(' ', $microtime);
return $sec.substr($usec,1);
}
// }}}
}
// }}}
?>

Change log

r72 by tychay on Sep 30, 2010   Diff
 Issue 5 :
- figure out how to turn on xdebug errors
@done(2010-09-30)
 Issue 29 :
- bugs: when timers are off we get
division by zero and zero adds @done
- call_user_func_array() now needs array
@done(2010-09-30)
Go to: 

Older revisions

r62 by tychay on May 6, 2009   Diff
 Issue 30 : added random routine support
 Issue 30 : added old style start stop
timer
 Issue 29 : made math in benchmarking
system precise
...
r56 by tychay on May 6, 2009   Diff
 Issue 29 : created and tested
benchmarking code
All revisions of this file

File info

Size: 11054 bytes, 341 lines
Powered by Google Project Hosting