Files
michaelschiemer/src/Framework/Performance/MemoryUsageTracker.php

133 lines
3.3 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Framework\Performance;
/**
* Tracking von Speicherverbrauch und Performance-Metriken.
*/
final class MemoryUsageTracker
{
/**
* @var array<string, float> Speichert Start-Zeitstempel für Messungen
*/
private array $timers = [];
/**
* @var array<string, int> Speichert Speicherverbrauch zu Beginn einer Messung
*/
private array $memoryUsage = [];
/**
* @var array<string, array{time: float, memory: int}> Gespeicherte Messpunkte
*/
private array $measurements = [];
/**
* Startet eine neue Zeitmessung.
*/
public function startTimer(string $name): void
{
$this->timers[$name] = microtime(true);
$this->memoryUsage[$name] = memory_get_usage(true);
}
/**
* Beendet eine Zeitmessung und gibt die verstrichene Zeit in Sekunden zurück.
*/
public function stopTimer(string $name): float
{
if (!isset($this->timers[$name])) {
return 0.0;
}
$startTime = $this->timers[$name];
$startMemory = $this->memoryUsage[$name];
$endTime = microtime(true);
$endMemory = memory_get_usage(true);
$timeElapsed = $endTime - $startTime;
$memoryDiff = $endMemory - $startMemory;
$this->measurements[$name] = [
'time' => $timeElapsed,
'memory' => $memoryDiff,
];
unset($this->timers[$name]);
unset($this->memoryUsage[$name]);
return $timeElapsed;
}
/**
* Gibt alle gespeicherten Messungen zurück.
*
* @return array<string, array{time: float, memory: int}>
*/
public function getMeasurements(): array
{
return $this->measurements;
}
/**
* Gibt die Messung für einen bestimmten Namen zurück.
*
* @return array{time: float, memory: int}|null
*/
public function getMeasurement(string $name): ?array
{
return $this->measurements[$name] ?? null;
}
/**
* Misst die Ausführungszeit einer Funktion.
*
* @param callable $callback Die auszuführende Funktion
* @param string $name Ein Name für diese Messung
* @return mixed Der Rückgabewert der Funktion
*/
public function measure(callable $callback, string $name): mixed
{
$this->startTimer($name);
$result = $callback();
$this->stopTimer($name);
return $result;
}
/**
* Gibt den aktuellen Speicherverbrauch in einem lesbaren Format zurück.
*/
public function getCurrentMemoryUsage(bool $realUsage = true): string
{
return $this->formatBytes(memory_get_usage($realUsage));
}
/**
* Gibt den maximalen Speicherverbrauch in einem lesbaren Format zurück.
*/
public function getPeakMemoryUsage(bool $realUsage = true): string
{
return $this->formatBytes(memory_get_peak_usage($realUsage));
}
/**
* Formatiert Bytes in ein lesbares Format.
*/
public function formatBytes(int $bytes, int $precision = 2): string
{
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= (1 << (10 * $pow));
return round($bytes, $precision) . ' ' . $units[$pow];
}
}