Symfony project is continuously making code changes and tweaks to improve performance across its codebase. In Symfony 6.3 we made the following relevant changes related to performance:
Improve Translation Message Extraction Performance
The translation:extract
command scans all your application files to find
translatable contents in order to help you update the translation files. It's a
very convenient command, but it can be slow in large codebases (e.g. 100,000 PHP
files or more) because it parses your PHP file contents using an AST.
In Symfony 6.3 we've improved this extraction process to only create AST for
PHP files that contain translation-related contents. Using a fast regular
expression, we detect if the file contains elements like ->trans(
and if
they don't, we don't try to parse their contents.
In practice, this has reduced the time to run that command by more than 70% in a 100,000 PHP file project.
Allow Disabling the XML Dumping of the Container
In debug mode, Symfony applications compile the service container information into an XML file. This file is used by various commands like:
config:dump-reference
debug:autowiring
debug:container
debug:router
lint:container
However, for very big applications (tens of thousands of files), generating this file can take up to a few seconds (and the generated file size is 20 MB). For some projects/developers, in those cases, the benefits of that file don't outweigh the overall performance decrease.
That's why in Symfony 6.3 we've introduced a new configuration option called
debug.container.dump
. Set it to false
to no longer dump the container
information into an XML file.
Improved Performance of Serializer Normalizers/Denormalizers
The Serializer component uses PHP arrays as an intermediary representation between the objects and their serialized contents. The normalizers/denormalizers take care of turning objects into arrays and vice versa.
In Symfony 6.3, we've added a getSupportedTypes(?string $format): array
method to normalizers/denormalizers so they can declare the type of objects that
they can handle and whether they are cacheable.
This way, Symfony tries to call this method first, instead of always calling the
supportsNormalization()
and supportsDenormalization()
methods. We've
already updated all built-in normalizers/denormalizers to add this method:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
class DateTimeNormalizer implements NormalizerInterface, DenormalizerInterface, CacheableSupportsMethodInterface
{
// ...
public function getSupportedTypes(?string $format): array
{
$isCacheable = __CLASS__ === static::class || $this->hasCacheableSupportsMethod();
return [
\DateTimeInterface::class => $isCacheable,
\DateTimeImmutable::class => $isCacheable,
\DateTime::class => $isCacheable,
];
}
}
Depending on the application, this can improve performance significantly. In our
own tests, certain applications reduced the time spent on getNormalizer()
calls by more than 80%.
Other Minor Changes
In addition to these big performance changes, we made some other minor changes like:
- Improve the performance of the
GlobResource
class used to find files in the Config component by inspecting the pattern to restrict the directories used for the search (change made by Nicolas Grekas in PR #49676) - Another improvement in the
GlobResource
class: reordering some conditions reduced the I/O instructions significantly (20%) (change made by Markus Staab in PR #50087) - Optimize the code of the LuhnValidator (change made by Max Beckers in PR #49216)
- Improve service container compilation time by reducing
InlineServiceDefinitionsPass
time 58% andContainerBuilder::inVendors()
time by 7% (change made by Nicolas Grekas in PR #48802)
Most of these improvements were possible thanks to Blackfire, which allows us to profile PHP applications to find the bottlenecks and then measure the performance gains.
Awesome Serializer improvements! Thanks!
This sounds great, especially the improvements in the serializer ;-)