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

Mathieu Santostefano
Contributed by Mathieu Santostefano in #49781

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

Ruud Kamphuis
Contributed by Ruud Kamphuis in #49487

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

Tugdual Saunier
Contributed by Tugdual Saunier in #49291

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% and ContainerBuilder::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.

Published in #Living on the edge