-
-
Notifications
You must be signed in to change notification settings - Fork 16
perf: Add caching layer for rendering operations #1287
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -23,6 +23,18 @@ | |||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| final class DocumentNameResolver implements DocumentNameResolverInterface | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| /** @var array<string, string> */ | ||||||||||||||||||||||||||||||||
| private array $absoluteUrlCache = []; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| /** @var array<string, string> */ | ||||||||||||||||||||||||||||||||
| private array $canonicalUrlCache = []; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| /** @var array<string, bool> */ | ||||||||||||||||||||||||||||||||
| private array $isAbsoluteCache = []; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| /** @var array<string, bool> */ | ||||||||||||||||||||||||||||||||
| private array $isAbsolutePathCache = []; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||
| * Returns the absolute path, including prefixing '/'. | ||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||
|
|
@@ -31,20 +43,31 @@ final class DocumentNameResolver implements DocumentNameResolverInterface | |||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||
| public function absoluteUrl(string $basePath, string $url): string | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| $uri = BaseUri::from($url); | ||||||||||||||||||||||||||||||||
| if ($uri->isAbsolute()) { | ||||||||||||||||||||||||||||||||
| return $url; | ||||||||||||||||||||||||||||||||
| $cacheKey = $basePath . '|' . $url; | ||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm wondering how much this would improve. There is not much heavy logic in this method. And I think the actual increase of memory usage does not add up to the small improvement this change has. A more specify benchmark on this method could help me to understand why this improves the speed.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
"new instance" means if DocumentNameResolver would use a new instance for every document but it is a Symfony service (singleton). |
||||||||||||||||||||||||||||||||
| if (isset($this->absoluteUrlCache[$cacheKey])) { | ||||||||||||||||||||||||||||||||
| return $this->absoluteUrlCache[$cacheKey]; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| // Cache URI analysis results separately by URL | ||||||||||||||||||||||||||||||||
| if (!isset($this->isAbsoluteCache[$url])) { | ||||||||||||||||||||||||||||||||
| $uri = BaseUri::from($url); | ||||||||||||||||||||||||||||||||
| $this->isAbsoluteCache[$url] = $uri->isAbsolute(); | ||||||||||||||||||||||||||||||||
| $this->isAbsolutePathCache[$url] = $uri->isAbsolutePath(); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if ($this->isAbsoluteCache[$url]) { | ||||||||||||||||||||||||||||||||
| return $this->absoluteUrlCache[$cacheKey] = $url; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if ($uri->isAbsolutePath()) { | ||||||||||||||||||||||||||||||||
| return $url; | ||||||||||||||||||||||||||||||||
| if ($this->isAbsolutePathCache[$url]) { | ||||||||||||||||||||||||||||||||
| return $this->absoluteUrlCache[$cacheKey] = $url; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if ($basePath === '/') { | ||||||||||||||||||||||||||||||||
| return $basePath . $url; | ||||||||||||||||||||||||||||||||
| return $this->absoluteUrlCache[$cacheKey] = $basePath . $url; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| return '/' . trim($basePath, '/') . '/' . $url; | ||||||||||||||||||||||||||||||||
| return $this->absoluteUrlCache[$cacheKey] = '/' . trim($basePath, '/') . '/' . $url; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||
|
|
@@ -57,8 +80,13 @@ public function absoluteUrl(string $basePath, string $url): string | |||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||
| public function canonicalUrl(string $basePath, string $url): string | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| $cacheKey = $basePath . '|' . $url; | ||||||||||||||||||||||||||||||||
| if (isset($this->canonicalUrlCache[$cacheKey])) { | ||||||||||||||||||||||||||||||||
| return $this->canonicalUrlCache[$cacheKey]; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if ($url[0] === '/') { | ||||||||||||||||||||||||||||||||
| return ltrim($url, '/'); | ||||||||||||||||||||||||||||||||
| return $this->canonicalUrlCache[$cacheKey] = ltrim($url, '/'); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| $dirNameParts = explode('/', $basePath); | ||||||||||||||||||||||||||||||||
|
|
@@ -78,6 +106,6 @@ public function canonicalUrl(string $basePath, string $url): string | |||||||||||||||||||||||||||||||
| $urlPass1[] = $part; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| return ltrim(implode('/', $dirNameParts) . '/' . implode('/', $urlPass1), '/'); | ||||||||||||||||||||||||||||||||
| return $this->canonicalUrlCache[$cacheKey] = ltrim(implode('/', $dirNameParts) . '/' . implode('/', $urlPass1), '/'); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We cannot make sure nobody is relying on this behavior. I concider this to be a breaking change. I see how this could improve the speed, but the actual impact of this change might be limited.
What we could do is introduce a new interface that can be implemented by the
PreNodeRendererthat already exist.PreNodeRendererCachableSupportswould have a methodcacheSupport() : boolWhen
preRenderersis not empty and allpreRenderersare cachable, we can create add it to cache.I think that will make sure we are backward compatible but still can cache the node renderers.