Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[DI] fix preloading script generation#36103

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
fabpot merged 1 commit intosymfony:4.4fromnicolas-grekas:fix-preload
Mar 18, 2020

Conversation

nicolas-grekas
Copy link
Member

@nicolas-grekasnicolas-grekas commentedMar 16, 2020
edited
Loading

QA
Branch?4.4
Bug fix?yes
New feature?no
Deprecations?no
Tickets-
LicenseMIT
Doc PR-

(fabbot failure is a false positive)

On master, we should work on being able to preload more classes (esp. all cache-warmup artifacts).

But for 4.4, this is good enough. Submitted as a bug fix because 1. the current code that deals with preloading kinda-works, but only on "dev" mode... and 2. fixing it provides a nice boost!

Small bench on a hello world:

  • before: 380 req/s
  • after: 580 req/s

That's +50%!

Pro-tip: adding a fewclass_exists() as done in this PR for the classes that are always used in the implementations (e.g.new Foo() in the constructor) will help the preload-script generator to work optimally. Without them, it will discover the symbols to preload only if they're found on methods.

Some of thoseclass_exists() are mandatory, in relation to anonymous classes andhttps://bugs.php.net/79349

teohhanhui reacted with thumbs down emojiBasster, Riches, walva, linaori, ilukac, Devristo, pfazzi, Ioni14, gillesbourgeat, yceruto, and 8 more reacted with hooray emojiteohhanhui reacted with confused emojidevrck reacted with rocket emoji
@teohhanhui
Copy link
Contributor

This pollutes the codebase... 😞

linaori and zmitic reacted with thumbs down emojirvanlaak reacted with confused emoji

@Pierstoval
Copy link
Contributor

Pierstoval commentedMar 17, 2020
edited
Loading

Is there a way to provide a "default" preloading script for all packages (that will execute theseclass_exists() calls) and generate a preloading script that would load all available preloading scripts in Symfony packages? This would allow to decouple the preloading from the classes themselves.

@nicolas-grekas
Copy link
MemberAuthor

nicolas-grekas commentedMar 17, 2020
edited
Loading

This pollutes the codebase... disappointed

see the description why this is needed.

Is there a way to provide a "default" preloading script for all packages

That's not possible, because the list of classes that need to be preloaded is conditional: vendor/ containing a package doesn't mean in any way it's going to be used at runtime. Putting theclass_exists() calls in each files is what makes the list conditional - with the DI container in control of what is actually wired.

@teohhanhui
Copy link
Contributor

Yeah, I know it's necessary to fix the preload, but is this really worth it?

@teohhanhui
Copy link
Contributor

What I mean is, even if the preload is not perfect, it's not fundamentally broken, even if the performance is not as good as it could be.

Is getting preload working such a priority that it's worth peppering these all over the codebase?

@nicolas-grekas
Copy link
MemberAuthor

@teohhanhui the numbers speak by themselves I think...

javiereguiluz, rvanlaak, Plopix, decompression, linaori, and zualex reacted with thumbs up emojiteohhanhui reacted with confused emojijacquesbh reacted with heart emoji

Copy link
Member

@NyholmNyholm left a comment
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Thank you Nicolas for working on this. I like that you managed to add tests to this feature.

I agree that this adds “class_exists” all over the place that can be hard to understand why. But once this PHP feature has matured one can safely remove these extra lines of code.

The performance benefit is impressive. Big 👍 for me.

@rvanlaak
Copy link
Contributor

rvanlaak commentedMar 17, 2020
edited
Loading

Theclass_exists call does not give many explicit info about why adding these lines is required for the preloading to do it's job.

Would introducing a new trait method to provide additional context via the method's name and phpdoc provide the same performance boost?

trait PreloaderTrait {publicfunctionpreload(string ...$classNames):void    {foreach($classNamesas$className) {class_exists($className);        }    }}
useSymfony\PreloaderTrait;preload(    FilesystemCache::class,    CoreExtension::class,    EscaperExtension::class,    OptimizerExtension::class,    StagingExtension::class,    ExtensionSet::class);

@nicolas-grekas
Copy link
MemberAuthor

nicolas-grekas commentedMar 17, 2020
edited
Loading

But once this PHP feature has matured one can safely remove these extra lines of code.

Actually not: this will remain and should become a new practice: we'll have to tell somewhere which classes are always needed by the implementations.

Here are the options:

  1. in a separate file. For Symfony that'd typically mean in service definitions. Using a tag looks the most sensible, thusthis project card.
  2. in the very same file as the implementation usingclass_exists() (what this PR does)
  3. in the very same file as the implementation, but using a convention (e.g. docblock annotations on the classes, or a specialprivate const OPCACHE_PRELOAD = [TheClasses::class, etc.], or similar.

3. might sound nice to most, but requires coordination in the PHP ecosystem: every project needs to embrace the convention or it will not work.
2. just works everywhere, no need for any special coordination in the ecosystem
1. is a band-aid we're going to need to take over packages that won't do2. (or3. if it becomes a thing).

@rvanlaak this doesn't work, we need code thatruns - a trait doesn't "run".

rvanlaak reacted with thumbs up emoji

@teohhanhui
Copy link
Contributor

Theclass_exists option seems the least maintainable, and is arguably also not PSR-1 compliant:

Files SHOULD either declare symbols (classes, functions, constants, etc.) or cause side-effects (e.g. generate output, change .ini settings, etc.) but SHOULD NOT do both.

@nicolas-grekas
Copy link
MemberAuthor

nicolas-grekas commentedMar 17, 2020
edited
Loading

Theclass_exists option seems the most maintainable to me. Same locality, greatest portability.

@ludofleury
Copy link

Impressive performance. at +50% it worth the maintenance cost. Hands down.

@nicolas-grekas
Copy link
MemberAuthor

Now with this comment before all calls:
// Help opcache.preload discover always-needed symbols

@Nyholm
Copy link
Member

👍

The comments sure are helpful

nicolas-grekas and rvanlaak reacted with thumbs up emoji

@Plopix
Copy link
Contributor

Plopix commentedMar 18, 2020
edited
Loading

+1 for me as well.
+50% !? Almost everything is justified for +50% perfs! And few lines to declare stuff are definitely worth it.

As usual: thanks a lot!

zmitic reacted with thumbs up emoji

@javiereguiluz
Copy link
Member

Thanks Nicolas! This is truly impressive!

Just asking: have you tried these changes in the Symfony Demo app? Should we expect similar ~50% performance improvements? Thanks!

@fabpot
Copy link
Member

Thank you@nicolas-grekas.

@fabpotfabpot merged commite457b24 intosymfony:4.4Mar 18, 2020
@nicolas-grekasnicolas-grekas deleted the fix-preload branchMarch 18, 2020 07:52
@fabpot
Copy link
Member

This is the same idea as when we add list of classes that we were concatenating in one file to make things faster. Definitely worth the extra manual work.

@nicolas-grekas
Copy link
MemberAuthor

nicolas-grekas commentedMar 18, 2020
edited
Loading

Thanks@fabpot

@javiereguiluz no way you'll see 50% on the demo apps. It'd be surprising if it'd spend that much time doing only loading. I hope real apps do a bit more :)

This was referencedMar 27, 2020
fabpot added a commit that referenced this pull requestApr 5, 2020
…lare extra classes to preload/services to not preload (nicolas-grekas)This PR was merged into the 5.1-dev branch.Discussion----------[DI] add tags `container.preload`/`.no_preload` to declare extra classes to preload/services to not preload| Q             | A| ------------- | ---| Branch?       | master| Bug fix?      | no| New feature?  | yes| Deprecations? | no| Tickets       | -| License       | MIT| Doc PR        | -To allow fine-grained declaration of sidekick classes in DI extensions.Follows#36103Commits-------fb04711 [DI] add tags `container.preload`/`.no_preload` to declare extra classes to preload/services to not preload
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@NyholmNyholmNyholm left review comments

@fabpotfabpotfabpot approved these changes

@dunglasdunglasAwaiting requested review from dunglasdunglas is a code owner

Assignees
No one assigned
Projects
None yet
Milestone
4.4
Development

Successfully merging this pull request may close these issues.

10 participants
@nicolas-grekas@teohhanhui@Pierstoval@rvanlaak@ludofleury@Nyholm@Plopix@javiereguiluz@fabpot@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp