Closed
Description
Description
Runtime cache on the serailizers / normalizers component system.
Example
We are using symfony/serializer as a dependency in Drupal. There is this module that seems to abuse this piece of code. and is causing very big delays (like 10-20% or request time) just finding the right normalizers.
Furhter details can be seen in Drupal's issue queue for jsonapi module: here
Direction
I've managed to drop overhead like 15-20 times with the following pseudo code.
I know it's not production ready but for you can get the idea:
Symfony\Component\Serializer\Serializer::getNormalizer($data, $format, array $context)
/**
* Returns a matching normalizer.
*
* @param mixed $data Data to get the serializer for
* @param string $format Format name, present to give the option to normalizers to act differently based on formats
* @param array $context Options available to the normalizer
*
* @return NormalizerInterface|null
*/
private function getNormalizer($data, $format, array $context)
{
static $cache = [];
$cid = get_class($data) . ':' . $format;
if (isset($cache[$cid])) {
return $cache[$cid];
}
foreach ($this->normalizers as $normalizer) {
if ($normalizer instanceof NormalizerInterface && $normalizer->supportsNormalization($data, $format, $context)) {
return $cache[$cid] = $normalizer;
}
}
}
Additional thoughts
- This can be moved to an internal property to be managed along-side the list of normalizers. Any time a normalizer list is mutated - reinitialize the property.
- At the moment this is not handling native types well (ints, strings) likely this overhead can be further reduced.
- Maybe just expose the getting of normalizers from private to protected, so this kind of optimizations can be implemented outside from here.