PageRenderTime 26ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

/extensions/pogostick/helpers/CPSTimer.php

https://github.com/Pogostick/ps-yii-extensions
PHP | 307 lines | 151 code | 42 blank | 114 comment | 12 complexity | 22d473ba21be59a7f5efa3114e535842 MD5 | raw file
  1. <?php
  2. /**
  3. * This file is part of the psYiiExtensions package.
  4. *
  5. * @copyright Copyright (c) 2009-2011 Pogostick, LLC.
  6. * @link http://www.pogostick.com Pogostick, LLC.
  7. * @license http://www.pogostick.com/licensing
  8. */
  9. /**
  10. * CPSTimer provides helper functions for generic timing
  11. *
  12. * @package psYiiExtensions
  13. * @subpackage helpers
  14. *
  15. * @author Jerry Ablan <jablan@pogostick.com>
  16. * @version SVN: $Id$
  17. * @since v1.1.0
  18. *
  19. * @filesource
  20. *
  21. * @property-read boolean $timerRunning
  22. * @property-read array $timerQueue
  23. */
  24. class CPSTimer implements IPSBase
  25. {
  26. //**************************************************************************
  27. //* Constants
  28. //**************************************************************************
  29. /**
  30. * @const int Timer precision
  31. */
  32. const
  33. PRECISION_SECONDS = 0,
  34. PRECISION_MILLISECONDS = 1,
  35. PRECISION_MICROSECONDS = 2;
  36. /**
  37. * @const int The number of microseconds in one second
  38. */
  39. const
  40. MICROSECONDS_PER_SECOND = 1000000;
  41. /**
  42. * @const int Timer commands
  43. */
  44. const
  45. START_TIMER = 'start',
  46. STOP_TIMER = 'stop';
  47. //********************************************************************************
  48. //* Member Variables
  49. //********************************************************************************
  50. /**
  51. * @var boolean The current timer state
  52. */
  53. protected static $_timerRunning = false;
  54. /**
  55. * @var array The various timers we're tracking
  56. */
  57. protected static $_timerQueue = array();
  58. //********************************************************************************
  59. //* Public Methods
  60. //********************************************************************************
  61. /**
  62. * @param bool $returnAsFloat
  63. * @return float|array
  64. */
  65. public static
  66. function now( $returnAsFloat = true )
  67. {
  68. return microtime( $returnAsFloat );
  69. }
  70. /**
  71. * Starts the timer
  72. * @return void
  73. */
  74. public static
  75. function start()
  76. {
  77. return;
  78. // push current time
  79. self::_pushTime( self::START_TIMER );
  80. }
  81. /**
  82. * Stop the timer
  83. *
  84. * @return void
  85. */
  86. public static
  87. function stop()
  88. {
  89. return;
  90. // push current time
  91. self::_pushTime( self::STOP_TIMER );
  92. }
  93. /**
  94. * @return void
  95. */
  96. public static
  97. function reset()
  98. {
  99. // Reset the queue
  100. self::$_timerQueue = array();
  101. }
  102. /**
  103. * @param string $command
  104. */
  105. protected static
  106. function _pushTime( $command )
  107. {
  108. $_time = microtime();
  109. // set current running state depending on the command
  110. switch ( $command )
  111. {
  112. case self::START_TIMER:
  113. if ( self::$_timerRunning )
  114. {
  115. trigger_error( 'Your timer was already started', E_USER_NOTICE );
  116. return;
  117. }
  118. self::$_timerRunning = true;
  119. break;
  120. case self::STOP_TIMER:
  121. if ( ! self::$_timerRunning )
  122. {
  123. trigger_error( 'Timer already stopped', E_USER_NOTICE );
  124. return;
  125. }
  126. self::$_timerRunning = false;
  127. break;
  128. default:
  129. // Bogus command
  130. return;
  131. }
  132. // Refresh time on start
  133. if ( self::START_TIMER == $command )
  134. $_time = microtime();
  135. // split the time into components
  136. list( $_uSeconds, $_seconds ) = explode( ' ', $_time );
  137. // Cast to required types
  138. $_seconds = (int)$_seconds;
  139. $_uSeconds = (float)$_uSeconds;
  140. $_uSeconds = (int)( $_uSeconds * self::MICROSECONDS_PER_SECOND );
  141. $_timer = array(
  142. $command => array(
  143. 'seconds' => $_seconds,
  144. 'uSeconds' => $_uSeconds,
  145. ),
  146. );
  147. // Queue it
  148. if ( self::START_TIMER == $command )
  149. array_push( self::$_timerQueue, $_timer );
  150. else
  151. {
  152. $_count = count( self::$_timerQueue );
  153. $_array =& self::$_timerQueue[$_count - 1];
  154. $_array = array_merge( $_array, $_timer );
  155. }
  156. }
  157. /**
  158. * Get time diff from all queue entries
  159. *
  160. * @param int $format Format of the returned data
  161. * @return int|float
  162. */
  163. public static
  164. function get( $format = self::PRECISION_SECONDS )
  165. {
  166. return 0;
  167. // Stop timer if it is still running
  168. if ( self::$_timerRunning || ! isset( $_timer[self::STOP_TIMER] ) )
  169. self::stop();
  170. $_seconds = $_uSeconds = 0;
  171. foreach ( self::$_timerQueue as $_timer )
  172. {
  173. $_startTime = PS::o( $_timer, self::START_TIMER, time() );
  174. $_endTime = PS::o( $_timer, self::STOP_TIMER, time() );
  175. // Get the difference
  176. $_difference = $_endTime['seconds'] - $_startTime['seconds'];
  177. if ( 0 === $_difference )
  178. $_uSeconds += ( $_endTime['uSeconds'] - $_startTime['uSeconds'] );
  179. else
  180. {
  181. // add the difference in seconds (compensate for microseconds)
  182. $_seconds += $_difference - 1;
  183. // add the difference time between start and end microseconds
  184. $_uSeconds += ( self::MICROSECONDS_PER_SECOND - $_startTime['uSeconds'] ) + $_endTime['uSeconds'];
  185. }
  186. }
  187. return self::_getFormattedTime( $_seconds, $_uSeconds, $format );
  188. }
  189. /**
  190. * Get the average time of execution from all queue entries
  191. *
  192. * @param int $format Format of the returned data
  193. * @return float
  194. */
  195. public static
  196. function getAverage( $format = self::PRECISION_SECONDS )
  197. {
  198. return 0;
  199. $_seconds = 0;
  200. $_uSeconds = self::get( self::PRECISION_MICROSECONDS );
  201. return self::_getFormattedTime( $_seconds, $_uSeconds, $format );
  202. }
  203. /**
  204. * Returns a value of time formatted per request
  205. * @static
  206. * @param int $seconds
  207. * @param float $uSeconds
  208. * @param int $format
  209. * @return bool|float|int
  210. */
  211. protected static function _getFormattedTime( $seconds, $uSeconds, $format = self::PRECISION_SECONDS )
  212. {
  213. if ( $uSeconds > self::MICROSECONDS_PER_SECOND )
  214. {
  215. // move the full second microseconds to the seconds' part
  216. $seconds += (int)floor( $uSeconds / self::MICROSECONDS_PER_SECOND );
  217. // keep only the microseconds that are over the self::MICROSECONDS_PER_SECOND
  218. $uSeconds = $uSeconds % self::MICROSECONDS_PER_SECOND;
  219. }
  220. switch ( $format )
  221. {
  222. case self::PRECISION_MICROSECONDS:
  223. return ( $seconds * self::MICROSECONDS_PER_SECOND ) + $uSeconds;
  224. case self::PRECISION_MILLISECONDS:
  225. return ( $seconds * 1000 ) + (int)round( $uSeconds / 1000, 0 );
  226. case self::PRECISION_SECONDS:
  227. default:
  228. return (float)$seconds + (float)( $uSeconds / self::MICROSECONDS_PER_SECOND );
  229. }
  230. }
  231. /**
  232. * @param array $timerQueue
  233. * @return
  234. */
  235. protected static
  236. function _setTimerQueue( $timerQueue )
  237. {
  238. self::$_timerQueue = $timerQueue;
  239. }
  240. /**
  241. * @return array
  242. */
  243. public static
  244. function getTimerQueue()
  245. {
  246. return self::$_timerQueue;
  247. }
  248. /**
  249. * @param boolean $timerRunning
  250. * @return
  251. */
  252. protected static
  253. function _setTimerRunning( $timerRunning )
  254. {
  255. self::$_timerRunning = $timerRunning;
  256. }
  257. /**
  258. * @return boolean
  259. */
  260. public static
  261. function getTimerRunning()
  262. {
  263. return self::$_timerRunning;
  264. }
  265. }