Files
michaelschiemer/tests/debug/test-reflection-performance.php
Michael Schiemer 36ef2a1e2c
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
fix: Gitea Traefik routing and connection pool optimization
- Remove middleware reference from Gitea Traefik labels (caused routing issues)
- Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s)
- Add explicit service reference in Traefik labels
- Fix intermittent 504 timeouts by improving PostgreSQL connection handling

Fixes Gitea unreachability via git.michaelschiemer.de
2025-11-09 14:46:15 +01:00

124 lines
4.7 KiB
PHP

<?php
declare(strict_types=1);
/**
* Performance Test: Native PHP Reflection vs Cached Reflection
*
* This test measures the actual performance difference between
* native PHP reflection and the cached reflection provider.
*/
require_once __DIR__ . '/../../vendor/autoload.php';
use App\Framework\Core\ValueObjects\ClassName;
use App\Framework\ReflectionLegacy\CachedReflectionProvider;
use ReflectionClass;
use ReflectionMethod;
// Test class
class TestClass {
public function __construct(
private string $param1,
private int $param2,
private ?object $param3 = null
) {}
public function testMethod(string $arg1, int $arg2): void {}
}
$iterations = 1000;
$className = TestClass::class;
echo "=== Reflection Performance Test ===\n\n";
echo "Testing $iterations iterations for class: $className\n\n";
// Test 1: Native ReflectionClass
$start = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
$reflection = new ReflectionClass($className);
$methods = $reflection->getMethods();
$constructor = $reflection->getConstructor();
if ($constructor) {
$params = $constructor->getParameters();
}
}
$nativeTime = microtime(true) - $start;
$nativeTimeMs = ($nativeTime * 1000);
$nativeTimePerOp = ($nativeTimeMs / $iterations);
echo "1. Native ReflectionClass:\n";
echo " Total: " . round($nativeTimeMs, 2) . " ms\n";
echo " Per operation: " . round($nativeTimePerOp, 4) . " ms\n";
echo " Per operation: " . round($nativeTimePerOp * 1000, 2) . " microseconds\n\n";
// Test 2: Native ReflectionMethod (most common operation)
$start = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
$reflection = new ReflectionMethod($className, 'testMethod');
$params = $reflection->getParameters();
foreach ($params as $param) {
$type = $param->getType();
$name = $param->getName();
$hasDefault = $param->isDefaultValueAvailable();
}
}
$nativeMethodTime = microtime(true) - $start;
$nativeMethodTimeMs = ($nativeMethodTime * 1000);
$nativeMethodTimePerOp = ($nativeMethodTimeMs / $iterations);
echo "2. Native ReflectionMethod (getParameters):\n";
echo " Total: " . round($nativeMethodTimeMs, 2) . " ms\n";
echo " Per operation: " . round($nativeMethodTimePerOp, 4) . " ms\n";
echo " Per operation: " . round($nativeMethodTimePerOp * 1000, 2) . " microseconds\n\n";
// Test 3: Cached ReflectionProvider (first run - no cache)
$provider = new CachedReflectionProvider();
$classNameObj = ClassName::create($className);
$start = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
$class = $provider->getClass($classNameObj);
$methods = $provider->getMethods($classNameObj);
$params = $provider->getMethodParameters($classNameObj, '__construct');
}
$cachedFirstTime = microtime(true) - $start;
$cachedFirstTimeMs = ($cachedFirstTime * 1000);
$cachedFirstTimePerOp = ($cachedFirstTimeMs / $iterations);
echo "3. Cached ReflectionProvider (first run - no cache):\n";
echo " Total: " . round($cachedFirstTimeMs, 2) . " ms\n";
echo " Per operation: " . round($cachedFirstTimePerOp, 4) . " ms\n";
echo " Per operation: " . round($cachedFirstTimePerOp * 1000, 2) . " microseconds\n\n";
// Test 4: Cached ReflectionProvider (cached - second run)
$start = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
$class = $provider->getClass($classNameObj);
$methods = $provider->getMethods($classNameObj);
$params = $provider->getMethodParameters($classNameObj, '__construct');
}
$cachedSecondTime = microtime(true) - $start;
$cachedSecondTimeMs = ($cachedSecondTime * 1000);
$cachedSecondTimePerOp = ($cachedSecondTimeMs / $iterations);
echo "4. Cached ReflectionProvider (cached - second run):\n";
echo " Total: " . round($cachedSecondTimeMs, 2) . " ms\n";
echo " Per operation: " . round($cachedSecondTimePerOp, 4) . " ms\n";
echo " Per operation: " . round($cachedSecondTimePerOp * 1000, 2) . " microseconds\n\n";
// Comparison
echo "=== Comparison ===\n";
$speedup = $nativeTimePerOp / $cachedSecondTimePerOp;
echo "Speedup (cached vs native): " . round($speedup, 2) . "x\n";
echo "Overhead (cached first vs native): " . round(($cachedFirstTimePerOp / $nativeTimePerOp - 1) * 100, 1) . "%\n\n";
// Reality check: How many reflection calls per request?
echo "=== Reality Check ===\n";
echo "Typical request might call getMethodParameters() 10-50 times\n";
echo "Native: " . round($nativeMethodTimePerOp * 50, 2) . " ms for 50 calls\n";
echo "Cached: " . round($cachedSecondTimePerOp * 50, 2) . " ms for 50 calls\n";
echo "Difference: " . round(($nativeMethodTimePerOp - $cachedSecondTimePerOp) * 50, 2) . " ms\n";
echo "Is this significant? " . (($nativeMethodTimePerOp - $cachedSecondTimePerOp) * 50 > 1 ? "YES (>1ms)" : "NO (<1ms)") . "\n";