$id, 'memory' => memory_get_usage(), 'memory_r' => static::formatMemoryBytes(memory_get_usage()), 'peaks' => [], 'ms_start' => microtime(true), ]; return $id; } /** * Ends an indicator to measure the performances. * * @param ?string $id Optional indicator identifier. * * @return array List of measurements. */ public static function end(?string $id = null) { if (!$id) { $id = end(static::$indicators)['id'] ?? ''; } $start_metrics = static::$indicators[$id] ?? []; if (!$start_metrics) { return []; } // ensure metrics were not ended already if (static::$indicators[$id]['ended'] ?? false) { // indicator was ended already return static::$indicators[$id]; } $now_ms = microtime(true); $now_memory = memory_get_usage(); $memory_used = $now_memory - $start_metrics['memory']; $ms_duration = $now_ms - $start_metrics['ms_start']; $end_metrics = [ 'ended' => true, 'ms_end' => $now_ms, 'memory_end' => $now_memory, 'ms_duration' => $ms_duration, 'memory_used' => $memory_used, 'memory_end_r' => static::formatMemoryBytes($now_memory), 'memory_peak_r' => static::formatMemoryBytes(memory_get_peak_usage()), 'memory_used_r' => static::formatMemoryBytes($memory_used), 'ms_duration_r' => round($ms_duration, 4), ]; static::$indicators[$id] = array_merge($start_metrics, $end_metrics); return static::$indicators[$id]; } /** * Registers a memory peak within an indicator. * * @param ?string $name Optional peak name for identification. * @param ?string $id Optional indicator identifier. * @param bool $onLast Whether to replace the last peak container. * * @return void * * @since 1.18.7 (J) - 1.8.7 (WP) added argument $name, $onLast, signature changed. */ public static function peak(?string $name = null, ?string $id = null, bool $onLast = false) { if (!$id) { $id = end(static::$indicators)['id'] ?? ''; } if (!(static::$indicators[$id] ?? [])) { return; } $now_memory = memory_get_usage(); // build peak container $peakContainer = [ 'name' => $name, 'memory' => $now_memory, 'memory_r' => static::formatMemoryBytes($now_memory), ]; if ($onLast) { // get last peak container $lastPeak = end(static::$indicators[$id]['peaks']); if ($lastPeak) { // replace last peak container array_splice(static::$indicators[$id]['peaks'], count(static::$indicators[$id]['peaks']) - 1, 1, [$peakContainer]); // do not proceed return; } } // push peak container static::$indicators[$id]['peaks'][] = $peakContainer; } /** * Ends all indicators and returns them. * * @param bool $end True to end all indicators before returning them. * * @return void */ public static function getAll(bool $end = true) { $list = []; foreach (static::$indicators as $id => $indicator) { if ($end) { static::end($id); } $list[$id] = static::$indicators[$id]; } return $list; } /** * Generates a random UUID v4. * * A UUID is a 16-octet (128-bit) number. In its canonical form, a UUID is represented by 32 * hexadecimal digits, displayed in five groups separated by hyphens, in the form 8-4-4-4-12 * for a total of 36 characters (32 alphanumeric characters and four hyphens). * * @return string */ public static function uuid() { return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', // 32 bits for "time_low" mt_rand(0, 0xffff), mt_rand(0, 0xffff), // 16 bits for "time_mid" mt_rand(0, 0xffff), // 16 bits for "time_hi_and_version", // four most significant bits holds version number 4 mt_rand(0, 0x0fff) | 0x4000, // 16 bits, 8 bits for "clk_seq_hi_res", // 8 bits for "clk_seq_low", // two most significant bits holds zero and one for variant DCE1.1 mt_rand(0, 0x3fff) | 0x8000, // 48 bits for "node" mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff) ); } /** * Helper method to format float values expressed in bytes (i.e. memory usage). * * @param float $bytes The number of bytes to format. * @param int $precision The precision to use for rounding. * * @return string The formatted bytes string. */ public static function formatMemoryBytes($bytes, $precision = 2) { $units = [ 'B', 'KB', 'MB', 'GB', 'TB', ]; $negative = (bool) ($bytes < 0); $bytes = $negative ? abs($bytes) : $bytes; $bytes = max($bytes, 0); $pow = floor(($bytes ? log($bytes) : 0) / log(1024)); $pow = min($pow, count($units) - 1); $bytes /= pow(1024, $pow); return ($negative ? '-' : '') . round($bytes, $precision) . ($units[$pow] ?? '?'); } }