# Performance Testing Comprehensive performance testing infrastructure for the Custom PHP Framework. ## Overview Performance testing suite including: - **Benchmarks** - Statistical performance measurement with P95/P99 percentiles - **Load Tests** - Concurrent request simulation - **Reports** - HTML, JSON, and Markdown report generation ## Directory Structure ``` tests/Performance/ ├── Benchmarks/ # Performance benchmarks │ ├── RoutingBenchmark.php │ ├── DatabaseBenchmark.php │ └── CacheBenchmark.php ├── LoadTests/ # Load testing utilities │ ├── LoadTestRunner.php │ └── LoadTestResult.php ├── Reports/ # Generated reports │ └── PerformanceReportGenerator.php ├── PerformanceTestCase.php # Base class for benchmarks └── PerformanceBenchmarkResult.php # Result value object ``` ## Running Performance Tests ### All Performance Tests ```bash # Run all performance benchmarks npm run test:perf # Or directly with Pest docker exec php ./vendor/bin/pest tests/Performance ``` ### Specific Benchmarks ```bash # Routing benchmarks npm run test:perf:routing # Database benchmarks npm run test:perf:database # Cache benchmarks npm run test:perf:cache ``` ### Generate Reports ```bash # Generate performance report npm run test:perf:report ``` ## Benchmark Categories ### 1. Routing Performance **File**: `tests/Performance/Benchmarks/RoutingBenchmark.php` **Tests**: - Static route matching - Dynamic route matching (with parameters) - Complex route matching (multiple parameters) - Route matching with query parameters - Route not found scenarios - POST route matching **Thresholds**: - Static routes: <0.1ms average - Dynamic routes: <0.5ms average - Complex routes: <1.0ms average ### 2. Database Performance **File**: `tests/Performance/Benchmarks/DatabaseBenchmark.php` **Tests**: - Simple SELECT queries - SELECT with JOIN operations - Bulk INSERT operations (100 records) - Transaction performance - Aggregate queries (COUNT, AVG, SUM) - Complex WHERE conditions **Thresholds**: - Simple queries: <1.0ms average - JOIN queries: <5.0ms average - Bulk inserts: <50.0ms average (100 records) - Transactions: <10.0ms average ### 3. Cache Performance **File**: `tests/Performance/Benchmarks/CacheBenchmark.php` **Tests**: - Cache SET operations - Cache GET operations (hit) - Cache GET operations (miss) - Cache remember pattern - Batch SET operations (100 items) - Large data caching (1MB) - Cache DELETE operations - Cache HAS operations **Thresholds**: - Cache SET: <0.5ms average - Cache GET (hit): <0.2ms average - Cache GET (miss): <0.3ms average - Batch operations: <20.0ms average (100 items) ## Load Testing ### LoadTestRunner Simulates concurrent users making requests to test performance under load. **Example Usage**: ```php use Tests\Performance\LoadTests\LoadTestRunner; use App\Framework\Core\ValueObjects\Duration; $runner = new LoadTestRunner(baseUrl: 'https://localhost'); $result = $runner->run( endpoint: '/api/users', concurrentUsers: 50, requestsPerUser: 100, rampUpTime: Duration::fromSeconds(10) ); echo $result->toString(); ``` **Metrics**: - Total requests - Successful requests - Error rate - Response time (avg, min, max, median, P95, P99) - Throughput (requests/second) ## Report Generation ### HTML Reports ```php use Tests\Performance\Reports\PerformanceReportGenerator; $generator = new PerformanceReportGenerator(); $html = $generator->generateHtmlReport( benchmarkResults: $results, loadTestResult: $loadTestResult ); $generator->saveReport($html, 'performance-report.html'); ``` ### JSON Reports ```php $json = $generator->generateJsonReport( benchmarkResults: $results, loadTestResult: $loadTestResult ); $generator->saveReport($json, 'performance-report.json'); ``` ### Markdown Reports ```php $markdown = $generator->generateMarkdownReport( benchmarkResults: $results, loadTestResult: $loadTestResult ); $generator->saveReport($markdown, 'performance-report.md'); ``` ## Creating Custom Benchmarks ### Step 1: Extend PerformanceTestCase ```php benchmark( operation: fn() => $this->service->performOperation(), iterations: 1000, name: 'My Custom Operation' ); // Assert performance threshold $this->assertPerformanceThreshold( $result, maxAvgTimeMs: 10.0, maxMemoryBytes: 1024 * 1024 // 1MB ); // Record metrics $this->recordBenchmark($result, PerformanceCategory::CUSTOM); return $result; } } ``` ### Step 2: Use benchmark() Method The `benchmark()` method provides: - **Warmup run** - Prevents cold start skewing results - **High-resolution timing** - Nanosecond precision with `hrtime()` - **Statistical analysis** - avg, min, max, median, P95, P99 - **Memory tracking** - Per-iteration memory usage - **Throughput calculation** - Operations per second ### Step 3: Set Performance Thresholds ```php // Time threshold only $this->assertPerformanceThreshold($result, maxAvgTimeMs: 5.0); // Time and memory thresholds $this->assertPerformanceThreshold( $result, maxAvgTimeMs: 10.0, maxMemoryBytes: 10 * 1024 * 1024 // 10MB ); ``` ## Performance Metrics Explained ### Timing Metrics - **Average Time**: Mean execution time across all iterations - **Min Time**: Fastest single execution - **Max Time**: Slowest single execution - **Median Time**: Middle value when sorted - **P95 Time**: 95th percentile - 95% of requests faster than this - **P99 Time**: 99th percentile - 99% of requests faster than this ### Memory Metrics - **Avg Memory**: Average memory used per iteration - **Peak Memory**: Maximum memory increase during benchmark ### Throughput Metrics - **Operations/Second**: How many operations can be completed per second - **Requests/Second**: For load tests, total requests per second ## Best Practices ### 1. Benchmark Design - **Sufficient Iterations**: Use enough iterations for statistical significance (min 100, prefer 1000+) - **Warmup**: The `benchmark()` method includes automatic warmup - **Isolation**: Test one operation at a time - **Realistic Data**: Use production-like data volumes ### 2. Performance Thresholds - **Set Realistic Thresholds**: Based on actual requirements, not arbitrary numbers - **Consider Percentiles**: P95/P99 more important than average for user experience - **Monitor Trends**: Track performance over time, not just absolute values ### 3. Load Testing - **Ramp-Up**: Use gradual ramp-up to avoid overwhelming the system - **Realistic Concurrency**: Match expected production load - **Error Handling**: Monitor error rates under load - **Resource Monitoring**: Track CPU, memory, database connections ### 4. Reporting - **Regular Reports**: Generate reports regularly to track trends - **Multiple Formats**: Use HTML for humans, JSON for automation - **Version Tracking**: Include version/commit info in reports - **Historical Comparison**: Compare against previous runs ## Performance Targets ### Response Time Targets - **API Endpoints**: <100ms P95 - **Database Queries**: <10ms P95 - **Cache Operations**: <1ms P95 - **Route Matching**: <0.5ms P95 ### Throughput Targets - **API Throughput**: >1000 req/sec - **Database Throughput**: >500 queries/sec - **Cache Throughput**: >10,000 ops/sec ### Resource Targets - **Memory**: <512MB for typical requests - **CPU**: <30% utilization at normal load - **Database Connections**: <20 concurrent connections ## Troubleshooting ### Slow Benchmarks **Issue**: Benchmarks taking too long **Solutions**: - Reduce iterations for initial testing - Check for N+1 query problems - Profile with Xdebug or Blackfire - Optimize database indexes ### High Memory Usage **Issue**: Memory usage exceeds thresholds **Solutions**: - Use batch processing for large datasets - Implement pagination - Clear large arrays/objects when done - Check for memory leaks ### Inconsistent Results **Issue**: High variance in benchmark results **Solutions**: - Increase iteration count - Run on dedicated hardware - Disable background processes - Use P95/P99 instead of max ## Integration with PerformanceCollector All benchmarks automatically integrate with the framework's PerformanceCollector: ```php $this->recordBenchmark($result, PerformanceCategory::ROUTING); ``` This allows: - Centralized performance tracking - Real-time monitoring dashboards - Historical performance analysis - Alerting on performance degradation ## CI/CD Integration ### GitHub Actions Example ```yaml name: Performance Tests on: [push, pull_request] jobs: performance: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Setup Docker run: make up - name: Run Performance Tests run: npm run test:perf - name: Generate Report run: npm run test:perf:report - name: Upload Report uses: actions/upload-artifact@v3 with: name: performance-report path: tests/Performance/Reports/ ``` ## Resources - **PerformanceTestCase**: Base class for all benchmarks - **PerformanceBenchmarkResult**: Result value object - **LoadTestRunner**: Concurrent load testing - **PerformanceReportGenerator**: Report generation in multiple formats - **PerformanceCollector**: Framework's performance tracking system ## Support For performance testing questions or issues: 1. Check this README 2. Review existing benchmarks for examples 3. Check framework performance documentation 4. Create GitHub issue if problem persists