-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Serializer] Add CompiledClassMetadataFactory #29117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Serializer] Add CompiledClassMetadataFactory #29117
Conversation
@fbourigault impressive work you did here! The Blackfire comparisons are incredible (the second one removes hundreds of thousands of function calls!!). In order to help the Symfony Docs team, we'd need a few more things here:
Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the performance, what is the difference between that and using a cache backed by the adapter relying on OPCache too ?
src/Symfony/Component/Serializer/Mapping/Factory/CompiledClassMetadataFactory.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Serializer/Mapping/Factory/CompiledClassMetadataFactory.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Serializer/Mapping/Factory/CompiledClassMetadataFactory.php
Outdated
Show resolved
Hide resolved
@stof here are the benchmark
I used the following code to use the $adapter = new ApcuAdapter('SymfonyMetadata');
$adapter = new PhpArrayAdapter(__DIR__.'/../metadata.cache', $adapter);
$classMetadataFactory = new CacheClassMetadataFactory(
new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())),
$adapter
); And here is the code for the warmup: $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$classMetadatas = [];
foreach([Category::class, Comment::class, Forum::class, Thread::class, User::class] as $class) {
$classMetadatas[strtr($class, '\\', '_')] = $classMetadataFactory->getMetadataFor($class);
}
$adapter = new PhpArrayAdapter(__DIR__.'/../../metadata.cache', new NullAdapter());
$adapter->warmUp($classMetadatas); I also switched from |
Yes :)
This is not yet defined, but it's maybe something to enable. Scanning the whole |
src/Symfony/Component/Serializer/Mapping/Factory/CompiledClassMetadataFactory.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Serializer/Mapping/Factory/CompiledClassMetadataFactoryDumper.php
Outdated
Show resolved
Hide resolved
I fixed all comments. Now I want to write the What about having something like: framework:
serializer:
metadata:
warmup:
- directory: '%kernel.project_dir%/src/Entity'
- class: App\Model\MyModelToWarmup
- directory: '@SomeBundle/Model' Third party bundles would be able to add entries to this list by prepending configuration. I also have a few questions:
|
Should I add the EDIT: I added it as suggestion. |
I rebased and fixed CS. I think this PR is ready now! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much for this perf boost!
src/Symfony/Component/Serializer/Mapping/Factory/ClassMetadataFactoryCompiler.php
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, that's it! just one minor comment: what about removing keys?
src/Symfony/Component/Serializer/Mapping/Factory/CompiledClassMetadataFactory.php
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great!
src/Symfony/Component/Serializer/CacheWarmer/CompiledClassMetadataCacheWarmer.php
Outdated
Show resolved
Hide resolved
Is this still relevant now that many things moved on the topic? |
Thank you @fbourigault. |
@fbourigault Can you have a look at |
This introduce a dumped
ClassMetadataFactoryInterface
implementation to speed up the serializer by leveraging PHP7 immutable array.Like for #28865, if the user have the opcache extension enabled, the compilation time will be skipped. The user will also have a performance boost when not using opcache as we are no longer fetching
ClassMetadata
from the PSR-6 cache.This allow to speed up the normalization (without opcache) by 9-12% depending on how many objects are involved in the graph:
On the
FrameworkBundle
side, I suggest to add aCacheWarmer
to dump the metadata array from configured class list. The list could have a good default which will load the classes found insrc/Entity
.Dumping the
ClassMetadata
Using the dumped
ClassMetadata
To do