-
Notifications
You must be signed in to change notification settings - Fork 0
Profiler
Razy includes a lightweight runtime performance profiler that captures memory, CPU, and timing snapshots at labeled checkpoints. Use it to identify bottlenecks, track memory growth, and measure execution time across code sections.
use Razy\Profiler;
$profiler = new Profiler(); // captures initial baseline
// ... do some work ...
$profiler->checkpoint('db_query');
// ... more work ...
$profiler->checkpoint('template_render');
// ... final work ...
$profiler->checkpoint('response_sent');
// Compare consecutive checkpoints
$report = $profiler->report();
print_r($report);Each checkpoint captures a snapshot of the runtime state at that moment:
$profiler = new Profiler();
// Add labeled checkpoints at key points
$profiler->checkpoint('boot');
$profiler->checkpoint('routes_loaded');
$profiler->checkpoint('controller_executed');
$profiler->checkpoint('view_rendered');
$profiler->checkpoint('response_sent');Rules:
-
Labels must be non-empty strings
-
Labels must be unique (throws on duplicates)
-
The constructor captures an initial
__initcheckpoint automatically
Compare consecutive checkpoints to see deltas between each step:
// Compare all consecutive pairs
$report = $profiler->report();
// [
// 'boot → routes_loaded' => [
// 'execution_time' => 0.0042,
// 'memory_usage' => 524288,
// ...
// ],
// 'routes_loaded → controller_executed' => [
// 'execution_time' => 0.0156,
// ...
// ],
// ]
// Compare specific checkpoints only
$report = $profiler->report(false, 'boot', 'controller_executed', 'response_sent');
// Compare each checkpoint against __init (total from start)
$report = $profiler->report(compareWithInit: true);
// [
// '__init → boot' => [...],
// '__init → routes_loaded' => [...],
// '__init → controller_executed' => [...],
// ]Compare a specific checkpoint against the initial baseline:
$delta = $profiler->reportTo('controller_executed');
// [
// 'execution_time' => 0.0198, // seconds since __init
// 'memory_usage' => 1048576, // bytes change
// 'memory_allocated' => 2097152, // bytes change
// 'output_buffer' => 0, // bytes change
// 'user_mode_time' => 0.015, // CPU seconds
// 'system_mode_time' => 0.003, // CPU seconds
// 'defined_functions' => ['myFunc1', 'myFunc2'], // new functions
// 'declared_classes' => ['App\\MyController'], // new classes
// ]Each checkpoint captures the following data:
| Metric | Type | Source | Description |
| --- | --- | --- | --- |
| memory_usage | int | memory_get_usage() | Heap memory in bytes |
| memory_allocated | int | memory_get_usage(true) | System-allocated memory in bytes |
| output_buffer | int | ob_get_length() | Output buffer size |
| user_mode_time | float | getrusage() | User CPU seconds |
| system_mode_time | float | getrusage() | System CPU seconds |
| execution_time | float | microtime(true) | Wall-clock time in seconds |
| defined_functions | array | get_defined_functions() | User-defined function names |
| declared_classes | array | get_declared_classes() | Declared class names |
-
Numeric metrics (memory, time): arithmetic difference
(checkpoint - baseline) -
Array metrics (functions, classes):
array_diff(checkpoint, baseline)— shows new entries only
$profiler = new Profiler();
$profiler->checkpoint('before_query');
$result = $db->query('SELECT * FROM users WHERE active = 1');
$profiler->checkpoint('after_query');
$delta = $profiler->reportTo('after_query');
echo "Query took: " . round($delta['execution_time'] * 1000, 2) . "ms\n";
echo "Memory delta: " . number_format($delta['memory_usage']) . " bytes\n";$profiler = new Profiler();
// Phase 1: Bootstrap
require 'bootstrap.php';
$profiler->checkpoint('bootstrap');
// Phase 2: Routing
$route = $router->match($request);
$profiler->checkpoint('routing');
// Phase 3: Controller
$response = $route->execute();
$profiler->checkpoint('controller');
// Phase 4: Rendering
echo $response->render();
$profiler->checkpoint('render');
// Full report
$report = $profiler->report(compareWithInit: true);
foreach ($report as $label => $metrics) {
printf(
"%s: %.2fms, %s memory\n",
$label,
$metrics['execution_time'] * 1000,
number_format($metrics['memory_usage'])
);
}$profiler = new Profiler();
$profiler->checkpoint('request_start');
// ... handle request ...
$profiler->checkpoint('request_end');
$delta = $profiler->reportTo('request_end');
if (count($delta['declared_classes']) > 50) {
error_log('Warning: ' . count($delta['declared_classes']) . ' new classes loaded this request');
}| Method | Signature | Description |
| --- | --- | --- |
| __construct | () | Create profiler with initial __init checkpoint |
| checkpoint | (string $label): Profiler | Capture snapshot (throws on empty/duplicate) |
| report | (bool $compareWithInit = false, string ...$labels): array | Consecutive delta report |
| reportTo | (string $label): array | Compare checkpoint to __init |