measure( 'http.request', PerformanceCategory::CONTROLLER, function () use ($tracker) { usleep(5000); // 5ms Controller-Logik // Database Query $tracker->measure( 'database.query', PerformanceCategory::DATABASE, function () { usleep(10000); // 10ms Query return ['users' => 100]; } ); // Cache Operation $tracker->measure( 'cache.get', PerformanceCategory::CACHE, function () { usleep(2000); // 2ms Cache return ['cached' => true]; } ); // Template Rendering $tracker->measure( 'template.render', PerformanceCategory::VIEW, function () use ($tracker) { usleep(3000); // 3ms Template // Nested: Asset Loading $tracker->measure( 'assets.load', PerformanceCategory::FILESYSTEM, function () { usleep(1000); // 1ms Assets } ); } ); return ['status' => 'success']; } ); // Flamegraph generieren echo "\nFlamegraph Data:\n"; $flamegraph = $tracker->generateFlamegraph(); foreach ($flamegraph as $entry) { echo sprintf( " %s → %.2f samples\n", $entry['stack_trace'], $entry['samples'] ); } // Timeline generieren echo "\nTimeline Events:\n"; $timeline = $tracker->generateTimeline(); foreach ($timeline as $event) { $indent = str_repeat(' ', $event['depth']); echo sprintf( " %s[%s] %s (%.2fms self, %.2fms total, %.2fMB memory)\n", $indent, $event['category'], $event['name'], $event['self_time_ms'], $event['duration_ms'], $event['memory_delta_mb'] ); } // Summary echo "\nPerformance Summary:\n"; $summary = $tracker->getSummary(); foreach ($summary as $key => $value) { echo sprintf(" %s: %s\n", $key, is_float($value) ? number_format($value, 2) : $value); } echo "\n" . str_repeat('=', 50) . "\n\n"; // Example 2: Flamegraph Export für Visualisierung echo "Example 2: Flamegraph Export (Brendan Gregg Format)\n"; echo str_repeat('-', 50) . "\n"; $tracker->reset(); // Reset für neues Beispiel // Komplexere Operation $tracker->measure( 'api.request', PerformanceCategory::API, function () use ($tracker) { usleep(2000); // Service Layer $tracker->measure( 'service.process', PerformanceCategory::CUSTOM, function () use ($tracker) { usleep(5000); // Repository $tracker->measure( 'repository.find', PerformanceCategory::DATABASE, function () { usleep(8000); } ); // Cache $tracker->measure( 'cache.set', PerformanceCategory::CACHE, function () { usleep(3000); } ); } ); // Response Transformation $tracker->measure( 'transformer.transform', PerformanceCategory::CUSTOM, function () { usleep(4000); } ); } ); $flamegraphData = $tracker->generateFlamegraph(); echo "\nFlamegraph Format für flamegraph.pl:\n"; echo "----------------------------------------\n"; foreach ($flamegraphData as $entry) { echo sprintf( "%s %d\n", $entry['stack_trace'], (int) ceil($entry['samples']) ); } // In Datei schreiben für flamegraph.pl Tool $flamegraphFile = __DIR__ . '/../tests/tmp/flamegraph.txt'; @mkdir(dirname($flamegraphFile), 0755, true); $output = []; foreach ($flamegraphData as $entry) { $output[] = sprintf( "%s %d", $entry['stack_trace'], (int) ceil($entry['samples']) ); } file_put_contents($flamegraphFile, implode("\n", $output)); echo "\nFlamegraph data saved to: {$flamegraphFile}\n"; echo "Generate SVG: flamegraph.pl {$flamegraphFile} > flamegraph.svg\n"; echo "\n" . str_repeat('=', 50) . "\n\n"; // Example 3: Chrome DevTools Timeline Export echo "Example 3: Chrome DevTools Timeline Export\n"; echo str_repeat('-', 50) . "\n"; $timeline = $tracker->generateTimeline(); // In Chrome Trace Event Format konvertieren $traceEvents = []; foreach ($timeline as $event) { // Begin Event $traceEvents[] = [ 'name' => $event['name'], 'cat' => $event['category'], 'ph' => 'B', // Begin 'ts' => (int)($event['start_time'] * 1_000_000), // Microseconds 'pid' => 1, 'tid' => 1, 'args' => $event['context'] ]; // End Event $traceEvents[] = [ 'name' => $event['name'], 'cat' => $event['category'], 'ph' => 'E', // End 'ts' => (int)($event['end_time'] * 1_000_000), 'pid' => 1, 'tid' => 1 ]; } $chromeTrace = [ 'traceEvents' => $traceEvents, 'displayTimeUnit' => 'ms', 'otherData' => [ 'version' => '1.0', 'framework' => 'Custom PHP Framework' ] ]; $chromeTraceFile = __DIR__ . '/../tests/tmp/chrome-trace.json'; file_put_contents($chromeTraceFile, json_encode($chromeTrace, JSON_PRETTY_PRINT)); echo "\nChrome Trace saved to: {$chromeTraceFile}\n"; echo "Open in Chrome: chrome://tracing → Load → {$chromeTraceFile}\n"; echo "\n" . str_repeat('=', 50) . "\n\n"; // Example 4: Performance Budget Validation echo "Example 4: Performance Budget Validation\n"; echo str_repeat('-', 50) . "\n"; $budgets = [ 'database.query' => 5, // max 5ms 'cache.get' => 1, // max 1ms 'api.request' => 20, // max 20ms ]; $violations = []; foreach ($timeline as $event) { // Check ob Operation ein Budget hat foreach ($budgets as $operation => $budget) { if (str_contains($event['name'], $operation)) { if ($event['duration_ms'] > $budget) { $violations[] = [ 'operation' => $event['name'], 'duration' => $event['duration_ms'], 'budget' => $budget, 'exceeded_by' => $event['duration_ms'] - $budget, 'exceeded_percentage' => (($event['duration_ms'] - $budget) / $budget) * 100 ]; } } } } if (!empty($violations)) { echo "\n⚠️ Performance Budget Violations:\n"; foreach ($violations as $violation) { echo sprintf( " • %s: %.2fms (budget: %.2fms, exceeded by %.2fms / %.1f%%)\n", $violation['operation'], $violation['duration'], $violation['budget'], $violation['exceeded_by'], $violation['exceeded_percentage'] ); } } else { echo "\n✅ All operations within performance budget!\n"; } echo "\n" . str_repeat('=', 50) . "\n\n"; // Example 5: Bottleneck Detection echo "Example 5: Automatic Bottleneck Detection\n"; echo str_repeat('-', 50) . "\n"; // Sortiere nach self_time_ms (Zeit ohne Children) $timelineCopy = $timeline; usort($timelineCopy, fn($a, $b) => $b['self_time_ms'] <=> $a['self_time_ms']); // Top 3 Bottlenecks $bottlenecks = array_slice($timelineCopy, 0, 3); echo "\nTop 3 Performance Bottlenecks (by self-time):\n"; foreach ($bottlenecks as $index => $bottleneck) { $percentage = ($bottleneck['self_time_ms'] / $bottleneck['duration_ms']) * 100; echo sprintf( " %d. %s [%s]\n" . " Self Time: %.2fms (%.1f%% of total %.2fms)\n" . " Memory: %.2fMB\n" . " Depth: %d\n", $index + 1, $bottleneck['name'], $bottleneck['category'], $bottleneck['self_time_ms'], $percentage, $bottleneck['duration_ms'], $bottleneck['memory_delta_mb'], $bottleneck['depth'] ); } echo "\n" . str_repeat('=', 50) . "\n\n"; // Example 6: Memory Usage Analysis echo "Example 6: Memory Usage Analysis\n"; echo str_repeat('-', 50) . "\n"; $totalMemory = 0; $memoryByCategory = []; foreach ($timeline as $event) { $totalMemory += $event['memory_delta_mb']; $category = $event['category']; if (!isset($memoryByCategory[$category])) { $memoryByCategory[$category] = 0; } $memoryByCategory[$category] += $event['memory_delta_mb']; } echo sprintf("\nTotal Memory Delta: %.2fMB\n", $totalMemory); echo "\nMemory Usage by Category:\n"; arsort($memoryByCategory); foreach ($memoryByCategory as $category => $memory) { $percentage = ($memory / max($totalMemory, 0.001)) * 100; echo sprintf( " • %s: %.2fMB (%.1f%%)\n", $category, $memory, $percentage ); } // High memory operations $highMemoryOps = array_filter($timeline, fn($e) => $e['memory_delta_mb'] > 0.5); if (!empty($highMemoryOps)) { echo "\n⚠️ High Memory Operations (>0.5MB):\n"; foreach ($highMemoryOps as $op) { echo sprintf( " • %s: %.2fMB\n", $op['name'], $op['memory_delta_mb'] ); } } echo "\n" . str_repeat('=', 50) . "\n\n"; echo "✅ Performance Profiling Examples completed!\n\n"; echo "Generated Files:\n"; echo " • {$flamegraphFile}\n"; echo " • {$chromeTraceFile}\n\n"; echo "Next Steps:\n"; echo " 1. Generate SVG: flamegraph.pl {$flamegraphFile} > flamegraph.svg\n"; echo " 2. View in Chrome: chrome://tracing → Load {$chromeTraceFile}\n"; echo " 3. Integrate into API endpoints for production monitoring\n\n";