PageRenderTime 49ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/system/classes/kohana/profiler.php

https://bitbucket.org/emolina/asesores
PHP | 385 lines | 188 code | 57 blank | 140 comment | 14 complexity | 214c61ea2a1a87139c8459264465030b MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php defined('SYSPATH') or die('No direct script access.');
  2. /**
  3. * Provides simple benchmarking and profiling. To display the statistics that
  4. * have been collected, load the `profiler/stats` [View]:
  5. *
  6. * echo View::factory('profiler/stats');
  7. *
  8. * @package Kohana
  9. * @category Helpers
  10. * @author Kohana Team
  11. * @copyright (c) 2009-2010 Kohana Team
  12. * @license http://kohanaframework.org/license
  13. */
  14. class Kohana_Profiler {
  15. /**
  16. * @var integer maximium number of application stats to keep
  17. */
  18. public static $rollover = 1000;
  19. /**
  20. * @var array collected benchmarks
  21. */
  22. protected static $_marks = array();
  23. /**
  24. * Starts a new benchmark and returns a unique token. The returned token
  25. * _must_ be used when stopping the benchmark.
  26. *
  27. * $token = Profiler::start('test', 'profiler');
  28. *
  29. * @param string group name
  30. * @param string benchmark name
  31. * @return string
  32. */
  33. public static function start($group, $name)
  34. {
  35. static $counter = 0;
  36. // Create a unique token based on the counter
  37. $token = 'kp/'.base_convert($counter++, 10, 32);
  38. Profiler::$_marks[$token] = array
  39. (
  40. 'group' => strtolower($group),
  41. 'name' => (string) $name,
  42. // Start the benchmark
  43. 'start_time' => microtime(TRUE),
  44. 'start_memory' => memory_get_usage(),
  45. // Set the stop keys without values
  46. 'stop_time' => FALSE,
  47. 'stop_memory' => FALSE,
  48. );
  49. return $token;
  50. }
  51. /**
  52. * Stops a benchmark.
  53. *
  54. * Profiler::stop($token);
  55. *
  56. * @param string token
  57. * @return void
  58. */
  59. public static function stop($token)
  60. {
  61. // Stop the benchmark
  62. Profiler::$_marks[$token]['stop_time'] = microtime(TRUE);
  63. Profiler::$_marks[$token]['stop_memory'] = memory_get_usage();
  64. }
  65. /**
  66. * Deletes a benchmark. If an error occurs during the benchmark, it is
  67. * recommended to delete the benchmark to prevent statistics from being
  68. * adversely affected.
  69. *
  70. * Profiler::delete($token);
  71. *
  72. * @param string token
  73. * @return void
  74. */
  75. public static function delete($token)
  76. {
  77. // Remove the benchmark
  78. unset(Profiler::$_marks[$token]);
  79. }
  80. /**
  81. * Returns all the benchmark tokens by group and name as an array.
  82. *
  83. * $groups = Profiler::groups();
  84. *
  85. * @return array
  86. */
  87. public static function groups()
  88. {
  89. $groups = array();
  90. foreach (Profiler::$_marks as $token => $mark)
  91. {
  92. // Sort the tokens by the group and name
  93. $groups[$mark['group']][$mark['name']][] = $token;
  94. }
  95. return $groups;
  96. }
  97. /**
  98. * Gets the min, max, average and total of a set of tokens as an array.
  99. *
  100. * $stats = Profiler::stats($tokens);
  101. *
  102. * @param array profiler tokens
  103. * @return array min, max, average, total
  104. * @uses Profiler::total
  105. */
  106. public static function stats(array $tokens)
  107. {
  108. // Min and max are unknown by default
  109. $min = $max = array(
  110. 'time' => NULL,
  111. 'memory' => NULL);
  112. // Total values are always integers
  113. $total = array(
  114. 'time' => 0,
  115. 'memory' => 0);
  116. foreach ($tokens as $token)
  117. {
  118. // Get the total time and memory for this benchmark
  119. list($time, $memory) = Profiler::total($token);
  120. if ($max['time'] === NULL OR $time > $max['time'])
  121. {
  122. // Set the maximum time
  123. $max['time'] = $time;
  124. }
  125. if ($min['time'] === NULL OR $time < $min['time'])
  126. {
  127. // Set the minimum time
  128. $min['time'] = $time;
  129. }
  130. // Increase the total time
  131. $total['time'] += $time;
  132. if ($max['memory'] === NULL OR $memory > $max['memory'])
  133. {
  134. // Set the maximum memory
  135. $max['memory'] = $memory;
  136. }
  137. if ($min['memory'] === NULL OR $memory < $min['memory'])
  138. {
  139. // Set the minimum memory
  140. $min['memory'] = $memory;
  141. }
  142. // Increase the total memory
  143. $total['memory'] += $memory;
  144. }
  145. // Determine the number of tokens
  146. $count = count($tokens);
  147. // Determine the averages
  148. $average = array(
  149. 'time' => $total['time'] / $count,
  150. 'memory' => $total['memory'] / $count);
  151. return array(
  152. 'min' => $min,
  153. 'max' => $max,
  154. 'total' => $total,
  155. 'average' => $average);
  156. }
  157. /**
  158. * Gets the min, max, average and total of profiler groups as an array.
  159. *
  160. * $stats = Profiler::group_stats('test');
  161. *
  162. * @param mixed single group name string, or array with group names; all groups by default
  163. * @return array min, max, average, total
  164. * @uses Profiler::groups
  165. * @uses Profiler::stats
  166. */
  167. public static function group_stats($groups = NULL)
  168. {
  169. // Which groups do we need to calculate stats for?
  170. $groups = ($groups === NULL)
  171. ? Profiler::groups()
  172. : array_intersect_key(Profiler::groups(), array_flip( (array) $groups));
  173. // All statistics
  174. $stats = array();
  175. foreach ($groups as $group => $names)
  176. {
  177. foreach ($names as $name => $tokens)
  178. {
  179. // Store the stats for each subgroup.
  180. // We only need the values for "total".
  181. $_stats = Profiler::stats($tokens);
  182. $stats[$group][$name] = $_stats['total'];
  183. }
  184. }
  185. // Group stats
  186. $groups = array();
  187. foreach ($stats as $group => $names)
  188. {
  189. // Min and max are unknown by default
  190. $groups[$group]['min'] = $groups[$group]['max'] = array(
  191. 'time' => NULL,
  192. 'memory' => NULL);
  193. // Total values are always integers
  194. $groups[$group]['total'] = array(
  195. 'time' => 0,
  196. 'memory' => 0);
  197. foreach ($names as $total)
  198. {
  199. if ( ! isset($groups[$group]['min']['time']) OR $groups[$group]['min']['time'] > $total['time'])
  200. {
  201. // Set the minimum time
  202. $groups[$group]['min']['time'] = $total['time'];
  203. }
  204. if ( ! isset($groups[$group]['min']['memory']) OR $groups[$group]['min']['memory'] > $total['memory'])
  205. {
  206. // Set the minimum memory
  207. $groups[$group]['min']['memory'] = $total['memory'];
  208. }
  209. if ( ! isset($groups[$group]['max']['time']) OR $groups[$group]['max']['time'] < $total['time'])
  210. {
  211. // Set the maximum time
  212. $groups[$group]['max']['time'] = $total['time'];
  213. }
  214. if ( ! isset($groups[$group]['max']['memory']) OR $groups[$group]['max']['memory'] < $total['memory'])
  215. {
  216. // Set the maximum memory
  217. $groups[$group]['max']['memory'] = $total['memory'];
  218. }
  219. // Increase the total time and memory
  220. $groups[$group]['total']['time'] += $total['time'];
  221. $groups[$group]['total']['memory'] += $total['memory'];
  222. }
  223. // Determine the number of names (subgroups)
  224. $count = count($names);
  225. // Determine the averages
  226. $groups[$group]['average']['time'] = $groups[$group]['total']['time'] / $count;
  227. $groups[$group]['average']['memory'] = $groups[$group]['total']['memory'] / $count;
  228. }
  229. return $groups;
  230. }
  231. /**
  232. * Gets the total execution time and memory usage of a benchmark as a list.
  233. *
  234. * list($time, $memory) = Profiler::total($token);
  235. *
  236. * @param string token
  237. * @return array execution time, memory
  238. */
  239. public static function total($token)
  240. {
  241. // Import the benchmark data
  242. $mark = Profiler::$_marks[$token];
  243. if ($mark['stop_time'] === FALSE)
  244. {
  245. // The benchmark has not been stopped yet
  246. $mark['stop_time'] = microtime(TRUE);
  247. $mark['stop_memory'] = memory_get_usage();
  248. }
  249. return array
  250. (
  251. // Total time in seconds
  252. $mark['stop_time'] - $mark['start_time'],
  253. // Amount of memory in bytes
  254. $mark['stop_memory'] - $mark['start_memory'],
  255. );
  256. }
  257. /**
  258. * Gets the total application run time and memory usage. Caches the result
  259. * so that it can be compared between requests.
  260. *
  261. * list($time, $memory) = Profiler::application();
  262. *
  263. * @return array execution time, memory
  264. * @uses Kohana::cache
  265. */
  266. public static function application()
  267. {
  268. // Load the stats from cache, which is valid for 1 day
  269. $stats = Kohana::cache('profiler_application_stats', NULL, 3600 * 24);
  270. if ( ! is_array($stats) OR $stats['count'] > Profiler::$rollover)
  271. {
  272. // Initialize the stats array
  273. $stats = array(
  274. 'min' => array(
  275. 'time' => NULL,
  276. 'memory' => NULL),
  277. 'max' => array(
  278. 'time' => NULL,
  279. 'memory' => NULL),
  280. 'total' => array(
  281. 'time' => NULL,
  282. 'memory' => NULL),
  283. 'count' => 0);
  284. }
  285. // Get the application run time
  286. $time = microtime(TRUE) - KOHANA_START_TIME;
  287. // Get the total memory usage
  288. $memory = memory_get_usage() - KOHANA_START_MEMORY;
  289. // Calculate max time
  290. if ($stats['max']['time'] === NULL OR $time > $stats['max']['time'])
  291. {
  292. $stats['max']['time'] = $time;
  293. }
  294. // Calculate min time
  295. if ($stats['min']['time'] === NULL OR $time < $stats['min']['time'])
  296. {
  297. $stats['min']['time'] = $time;
  298. }
  299. // Add to total time
  300. $stats['total']['time'] += $time;
  301. // Calculate max memory
  302. if ($stats['max']['memory'] === NULL OR $memory > $stats['max']['memory'])
  303. {
  304. $stats['max']['memory'] = $memory;
  305. }
  306. // Calculate min memory
  307. if ($stats['min']['memory'] === NULL OR $memory < $stats['min']['memory'])
  308. {
  309. $stats['min']['memory'] = $memory;
  310. }
  311. // Add to total memory
  312. $stats['total']['memory'] += $memory;
  313. // Another mark has been added to the stats
  314. $stats['count']++;
  315. // Determine the averages
  316. $stats['average'] = array(
  317. 'time' => $stats['total']['time'] / $stats['count'],
  318. 'memory' => $stats['total']['memory'] / $stats['count']);
  319. // Cache the new stats
  320. Kohana::cache('profiler_application_stats', $stats);
  321. // Set the current application execution time and memory
  322. // Do NOT cache these, they are specific to the current request only
  323. $stats['current']['time'] = $time;
  324. $stats['current']['memory'] = $memory;
  325. // Return the total application run time and memory usage
  326. return $stats;
  327. }
  328. } // End Profiler