minor #24228 [Serializer] Add local cache to normalizers (nicolas-grekas)

This PR was merged into the 3.4 branch.

Discussion
----------

[Serializer] Add local cache to normalizers

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #24206
| License       | MIT
| Doc PR        | -

Should help making the Serializer a bit faster.

Commits
-------

b0c5cf0 [Serializer] Add local cache to normalizers
This commit is contained in:
Nicolas Grekas 2017-09-20 07:22:30 +02:00
commit aad62c427c
8 changed files with 43 additions and 51 deletions

View File

@ -36,6 +36,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
private $propertyTypeExtractor;
private $attributesCache = array();
private $cache = array();
public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyTypeExtractorInterface $propertyTypeExtractor = null)
{
@ -49,7 +50,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
*/
public function supportsNormalization($data, $format = null)
{
return is_object($data) && !$data instanceof \Traversable;
return \is_object($data) && !$data instanceof \Traversable;
}
/**
@ -163,7 +164,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
*/
public function supportsDenormalization($data, $type, $format = null)
{
return class_exists($type);
return isset($this->cache[$type]) ? $this->cache[$type] : $this->cache[$type] = class_exists($type);
}
/**

View File

@ -66,7 +66,7 @@ class ArrayDenormalizer implements DenormalizerInterface, SerializerAwareInterfa
*/
public function supportsDenormalization($data, $type, $format = null/*, array $context = array()*/)
{
$context = func_num_args() > 3 ? func_get_arg(3) : array();
$context = \func_num_args() > 3 ? func_get_arg(3) : array();
return '[]' === substr($type, -2)
&& $this->serializer->supportsDenormalization($data, substr($type, 0, -2), $format, $context);

View File

@ -19,6 +19,8 @@ use Symfony\Component\Serializer\SerializerAwareTrait;
*/
class CustomNormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface
{
private $cache = array();
use SerializerAwareTrait;
/**
@ -64,10 +66,14 @@ class CustomNormalizer implements NormalizerInterface, DenormalizerInterface, Se
*/
public function supportsDenormalization($data, $type, $format = null)
{
if (!class_exists($type)) {
return false;
if (isset($this->cache[$type])) {
return $this->cache[$type];
}
return is_subclass_of($type, 'Symfony\Component\Serializer\Normalizer\DenormalizableInterface');
if (!class_exists($type)) {
return $this->cache[$type] = false;
}
return $this->cache[$type] = is_subclass_of($type, 'Symfony\Component\Serializer\Normalizer\DenormalizableInterface');
}
}

View File

@ -25,6 +25,12 @@ use Symfony\Component\Serializer\Exception\UnexpectedValueException;
*/
class DataUriNormalizer implements NormalizerInterface, DenormalizerInterface
{
private static $supportedTypes = array(
\SplFileInfo::class => true,
\SplFileObject::class => true,
File::class => true,
);
/**
* @var MimeTypeGuesserInterface
*/
@ -107,13 +113,7 @@ class DataUriNormalizer implements NormalizerInterface, DenormalizerInterface
*/
public function supportsDenormalization($data, $type, $format = null)
{
$supportedTypes = array(
\SplFileInfo::class => true,
\SplFileObject::class => true,
'Symfony\Component\HttpFoundation\File\File' => true,
);
return isset($supportedTypes[$type]);
return isset(self::$supportedTypes[$type]);
}
/**

View File

@ -31,6 +31,12 @@ class DateTimeNormalizer implements NormalizerInterface, DenormalizerInterface
private $format;
private $timezone;
private static $supportedTypes = array(
\DateTimeInterface::class => true,
\DateTimeImmutable::class => true,
\DateTime::class => true,
);
/**
* @param string $format
* @param \DateTimeZone|null $timezone
@ -115,13 +121,7 @@ class DateTimeNormalizer implements NormalizerInterface, DenormalizerInterface
*/
public function supportsDenormalization($data, $type, $format = null)
{
$supportedTypes = array(
\DateTimeInterface::class => true,
\DateTimeImmutable::class => true,
\DateTime::class => true,
);
return isset($supportedTypes[$type]);
return isset(self::$supportedTypes[$type]);
}
/**

View File

@ -35,13 +35,14 @@ namespace Symfony\Component\Serializer\Normalizer;
class GetSetMethodNormalizer extends AbstractObjectNormalizer
{
private static $setterAccessibleCache = array();
private $cache = array();
/**
* {@inheritdoc}
*/
public function supportsNormalization($data, $format = null)
{
return parent::supportsNormalization($data, $format) && $this->supports(get_class($data));
return parent::supportsNormalization($data, $format) && (isset($this->cache[$type = \get_class($data)]) ? $this->cache[$type] : $this->cache[$type] = $this->supports($type));
}
/**
@ -49,7 +50,7 @@ class GetSetMethodNormalizer extends AbstractObjectNormalizer
*/
public function supportsDenormalization($data, $type, $format = null)
{
return parent::supportsDenormalization($data, $type, $format) && $this->supports($type);
return parent::supportsDenormalization($data, $type, $format) && (isset($this->cache[$type]) ? $this->cache[$type] : $this->cache[$type] = $this->supports($type));
}
/**

View File

@ -30,12 +30,14 @@ namespace Symfony\Component\Serializer\Normalizer;
*/
class PropertyNormalizer extends AbstractObjectNormalizer
{
private $cache = array();
/**
* {@inheritdoc}
*/
public function supportsNormalization($data, $format = null)
{
return parent::supportsNormalization($data, $format) && $this->supports(get_class($data));
return parent::supportsNormalization($data, $format) && (isset($this->cache[$type = \get_class($data)]) ? $this->cache[$type] : $this->cache[$type] = $this->supports($type));
}
/**
@ -43,7 +45,7 @@ class PropertyNormalizer extends AbstractObjectNormalizer
*/
public function supportsDenormalization($data, $type, $format = null)
{
return parent::supportsDenormalization($data, $type, $format) && $this->supports($type);
return parent::supportsDenormalization($data, $type, $format) && (isset($this->cache[$type]) ? $this->cache[$type] : $this->cache[$type] = $this->supports($type));
}
/**

View File

@ -171,7 +171,15 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
*/
public function denormalize($data, $type, $format = null, array $context = array())
{
return $this->denormalizeObject($data, $type, $format, $context);
if (!$this->normalizers) {
throw new LogicException('You must register at least one normalizer to be able to denormalize objects.');
}
if ($normalizer = $this->getDenormalizer($data, $type, $format, $context)) {
return $normalizer->denormalize($data, $type, $format, $context);
}
throw new UnexpectedValueException(sprintf('Could not denormalize object of type %s, no supporting normalizer found.', $type));
}
/**
@ -269,32 +277,6 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
return $this->decoder->decode($data, $format, $context);
}
/**
* Denormalizes data back into an object of the given class.
*
* @param mixed $data data to restore
* @param string $class the expected class to instantiate
* @param string $format format name, present to give the option to normalizers to act differently based on formats
* @param array $context The context data for this particular denormalization
*
* @return object
*
* @throws LogicException
* @throws UnexpectedValueException
*/
private function denormalizeObject($data, $class, $format, array $context = array())
{
if (!$this->normalizers) {
throw new LogicException('You must register at least one normalizer to be able to denormalize objects.');
}
if ($normalizer = $this->getDenormalizer($data, $class, $format, $context)) {
return $normalizer->denormalize($data, $class, $format, $context);
}
throw new UnexpectedValueException(sprintf('Could not denormalize object of type %s, no supporting normalizer found.', $class));
}
/**
* {@inheritdoc}
*/