From 5d18409a6c0d93f7fb02ad35bfe2984d6b841b1e Mon Sep 17 00:00:00 2001 From: Martin Linzmayer Date: Fri, 17 Jul 2026 01:47:27 +0200 Subject: [PATCH] perf: introduce source code caching to improve duplicate frames --- .../FrameContextifierIntegration.php | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/Integration/FrameContextifierIntegration.php b/src/Integration/FrameContextifierIntegration.php index f0ff6f59b..31729b7af 100644 --- a/src/Integration/FrameContextifierIntegration.php +++ b/src/Integration/FrameContextifierIntegration.php @@ -25,6 +25,15 @@ final class FrameContextifierIntegration implements IntegrationInterface */ private $logger; + /** + * @var array The excerpts read while processing the current event, keyed by "file:line" + */ + private $excerptCache = []; + /** * Creates a new instance of this integration. * @@ -54,16 +63,20 @@ public function setupOnce(): void return $event; } - $stacktrace = $event->getStacktrace(); + try { + $stacktrace = $event->getStacktrace(); - if ($stacktrace !== null) { - $integration->addContextToStacktraceFrames($maxContextLines, $stacktrace); - } + if ($stacktrace !== null) { + $integration->addContextToStacktraceFrames($maxContextLines, $stacktrace); + } - foreach ($event->getExceptions() as $exception) { - if ($exception->getStacktrace() !== null) { - $integration->addContextToStacktraceFrames($maxContextLines, $exception->getStacktrace()); + foreach ($event->getExceptions() as $exception) { + if ($exception->getStacktrace() !== null) { + $integration->addContextToStacktraceFrames($maxContextLines, $exception->getStacktrace()); + } } + } finally { + $integration->excerptCache = []; } return $event; @@ -122,6 +135,12 @@ private function addContextToStacktraceFrame(int $maxContextLines, Frame $frame) */ private function getSourceCodeExcerpt(int $maxContextLines, string $filePath, int $lineNumber): array { + $cacheKey = $filePath . ':' . $lineNumber; + + if (isset($this->excerptCache[$cacheKey])) { + return $this->excerptCache[$cacheKey]; + } + $frame = [ 'pre_context' => [], 'context_line' => null, @@ -156,6 +175,8 @@ private function getSourceCodeExcerpt(int $maxContextLines, string $filePath, in $file->next(); } + + $this->excerptCache[$cacheKey] = $frame; } catch (\Throwable $exception) { $this->logger->warning( \sprintf('Failed to get the source code excerpt for the file "%s".', $filePath),