10000 minor #30525 [PropertyInfo] Use a single cache item per method (devia… · symfony/symfony@248aff5 · GitHub
[go: up one dir, main page]

Skip to content

Commit 248aff5

Browse files
committed
minor #30525 [PropertyInfo] Use a single cache item per method (deviantintegral)
This PR was merged into the 4.3-dev branch. Discussion ---------- [PropertyInfo] Use a single cache item per method | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #29977 | License | MIT | Doc PR | none Replaces #30523 with a rebase to master. This PR changes how property metadata is cached, significantly reducing the number of calls made between PHP and the backend cache. Instead of storing one cache item per method and set of arguments, a single cache item is stored per method. This matches well with real-world use, where most properties in an object will need to be inspected. Note that the absolute numbers in the above PR are best case. In production environments where memcache is on a remote server, we were seeing multiple seconds consumed by memcache calls. Commits ------- 2a4f8a1 [PropertyInfo] Use a single cache item per method
2 parents 8da7686 + 2a4f8a1 commit 248aff5

File tree

1 file changed

+27
-8
lines changed

1 file changed

+27
-8
lines changed

src/Symfony/Component/PropertyInfo/PropertyInfoCacheExtractor.php

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ class PropertyInfoCacheExtractor implements PropertyInfoExtractorInterface, Prop
2424
{
2525
private $propertyInfoExtractor;
2626
private $cacheItemPool;
27+
28+
/**
29+
* A cache of property information, first keyed by the method called and
30+
* then by the serialized method arguments.
31+
*
32+
* @var array
33+
*/
2734
private $arrayCache = [];
2835

2936
public function __construct(PropertyInfoExtractorInterface $propertyInfoExtractor, CacheItemPoolInterface $cacheItemPool)
@@ -103,22 +110,34 @@ private function extract(string $method, array $arguments)
103110
}
104111

105112
// Calling rawurlencode escapes special characters not allowed in PSR-6's keys
106-
$key = rawurlencode($method.'.'.$serializedArguments);
107-
108-
if (\array_key_exists($key, $this->arrayCache)) {
109-
return $this->arrayCache[$key];
113+
$encodedMethod = \rawurlencode($method);
114+
if (\array_key_exists($encodedMethod, $this->arrayCache) && \array_key_exists($serializedArguments, $ 8000 this->arrayCache[$encodedMethod])) {
115+
return $this->arrayCache[$encodedMethod][$serializedArguments];
110116
}
111117

112-
$item = $this->cacheItemPool->getItem($key);
118+
$item = $this->cacheItemPool->getItem($encodedMethod);
113119

120+
$data = $item->get();
114121
if ($item->isHit()) {
115-
return $this->arrayCache[$key] = $item->get();
122+
$this->arrayCache[$encodedMethod] = $data[$encodedMethod];
123+
// Only match if the specific arguments have been cached.
124+
if (\array_key_exists($serializedArguments, $data[$encodedMethod])) {
125+
return $this->arrayCache[$encodedMethod][$serializedArguments];
126+
}
127+
}
128+
129+
// It's possible that the method has been called, but with different
130+
// arguments, in which case $data will already be initialized.
131+
if (!$data) {
132+
$data = [];
116133
}
117134

118135
$value = $this->propertyInfoExtractor->{$method}(...$arguments);
119-
$item->set($value);
136+
$data[$encodedMethod][$serializedArguments] = $value;
137+
$this->arrayCache[$encodedMethod][$serializedArguments] = $value;
138+
$item->set($data);
120139
$this->cacheItemPool->save($item);
121140

122-
return $this->arrayCache[$key] = $value;
141+
return $this->arrayCache[$encodedMethod][$serializedArguments];
123142
}
124143
}

0 commit comments

Comments
 (0)
0