Lab 14: Performance Profiling

Time: 60 minutes | Level: Architect | Docker: docker run -it --rm php:8.3-cli bash

Overview

Performance profiling identifies bottlenecks in PHP applications. This lab covers manual microtime profiling, OPcache optimization, realpath cache tuning, PHP preloading concepts, and benchmarking core PHP constructs.


Step 1: Benchmarking Framework

<?php
class Profiler {
    private array $timings = [];
    private array $memory  = [];
    
    public function measure(string $name, callable $fn, int $iterations = 1): mixed {
        $memBefore = memory_get_usage(true);
        $timings   = [];
        $result    = null;
        
        // Warmup
        $fn();
        
        for ($i = 0; $i < $iterations; $i++) {
            $start  = hrtime(true);
            $result = $fn();
            $timings[] = hrtime(true) - $start;
        }
        
        sort($timings);
        $this->timings[$name] = [
            'min'    => min($timings) / 1_000_000,
            'max'    => max($timings) / 1_000_000,
            'avg'    => array_sum($timings) / count($timings) / 1_000_000,
            'median' => $timings[(int)(count($timings) / 2)] / 1_000_000,
            'p95'    => $timings[(int)(count($timings) * 0.95)] / 1_000_000,
        ];
        $this->memory[$name] = (memory_get_usage(true) - $memBefore) / 1024;
        
        return $result;
    }
    
    public function report(): void {
        printf("\n%-35s %8s %8s %8s %8s %8s %8s\n",
            'Benchmark', 'Min(ms)', 'Avg(ms)', 'Median', 'P95', 'Max', 'Memory');
        echo str_repeat('', 95) . "\n";
        
        foreach ($this->timings as $name => $t) {
            printf("%-35s %8.3f %8.3f %8.3f %8.3f %8.3f %6.1fKB\n",
                $name,
                $t['min'], $t['avg'], $t['median'], $t['p95'], $t['max'],
                $this->memory[$name]
            );
        }
    }
    
    public function compare(string $baseline, string $candidate): void {
        $b = $this->timings[$baseline]['avg'] ?? 0;
        $c = $this->timings[$candidate]['avg'] ?? 0;
        $ratio = $b > 0 ? $b / $c : 0;
        $diff  = round(($c - $b) / $b * 100, 1);
        $symbol = $c < $b ? '🚀 faster' : '🐌 slower';
        printf("  %s vs %s: %+.1f%% (%s)\n", $candidate, $baseline, -$diff, $symbol);
    }
}

$p = new Profiler();
echo "Profiler ready. hrtime() precision: " . hrtime(true) . " ns\n";

Step 2: Array Iteration Benchmarks

📸 Verified Output:

💡 for loop beats foreach slightly because PHP doesn't need to create an iterator. array_map has overhead for the callback invocation. For pure iteration, for is fastest; for readability and moderate performance, foreach is preferred.


Step 3: String Operation Benchmarks


Step 4: OPcache Configuration Analysis


Step 5: Realpath Cache & File System Performance


Step 6: PHP Preloading (opcache.preload)


Step 7: Memory Profiling

📸 Verified Output:


Step 8: Capstone — Comprehensive Performance Suite

📸 Verified Output:


Summary

Technique
Method
Expected Impact

Loop style

for > foreach > array_map

10-20% on loop-heavy code

String building

str_repeat > implode > .=

10x+ for large repetition

OPcache enable

opcache.enable=1

30-50% on typical apps

Validate timestamps off

opcache.validate_timestamps=0

10-30% in production

JIT

opcache.jit=1255

2-5x on CPU-bound code

Preloading

opcache.preload

5-15% on class-heavy apps

Realpath cache

realpath_cache_size=4096k

Reduces stat() syscalls

Memory

unset() + generators

Reduces GC pressure

SplFixedArray

For large integer arrays

~24% memory savings

hrtime() profiling

Nanosecond profiling

Better than microtime()

Last updated