Skip to content

Navigation Menu

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

Appearance settings

[performance] Symfony Kernel::boot() in dev mode on Alpine #35009

Copy link
Copy link
Closed
@bastnic

Description

@bastnic
Issue body actions

This is a follow-up of this discussion.

Alpine is the default docker linux base distribution. It's widely used. It's based on musl libc, and so, it's quite different of traditional linux distribution as Debian. One the difference is that glob does not handle GLOB_BRACE.

I knew about it from an old issue on composer that we already experienced.

On a big project, we had quite castrophous boot time, and I finally checked on it.

The first thing is that Iterator/SortableIterator.php/44-46 cost an enormous amout of time and is called 22k time.

Searching why, It seems that we never enter is the optimized path here

if (0 !== strpos($this->prefix, 'phar://') && false === strpos($this->pattern, '/**/') && (\defined('GLOB_BRACE') || false === strpos($this->pattern, '{'))) {
.

I had that in Kernel::configureContainer:

const CONFIG_EXTS = '.{php,xml,yaml,yml}';
// ... 
$loader->load($confDir . '/{packages}/*' . self::CONFIG_EXTS, 'glob'); 
$loader->load($confDir . '/{packages}/' . $this->environment . '/**/*' . self::CONFIG_EXTS, 'glob');
$loader->load($confDir . '/{services}' . self::CONFIG_EXTS, 'glob');

and in services.yaml:

Lib\Core\:
    resource: '../src/*'
    exclude: '../src/{Entity,Migrations,Translation,Tests,Kernel.php,PHPStan,Fixtures,Traits}'

As I don't have GLOB_BRACE and every pattern given contains a brace, it always fallback on the symfony/finder implementation which is wayyy slower.

By removing the /**/*, and only searching into yaml extension, I expect to be in the fast path. But the brackets on {packages} and {services} prevents it. By removing them it goes into the fast path. And gives a clear boost.

$loader->load($confDir . '/packages/*' . self::CONFIG_EXTS, 'glob');

if (is_dir($confDir . '/packages/' . $this->environment)) {
	$loader->load($confDir . '/packages/' . $this->environment . '/*' . self::CONFIG_EXTS, 'glob');
}
$loader->load($confDir . '/services.yaml');

I didn't see any drwabacks (and I have a very extensive tests suites).

Rest the case with multiple option separated by comma in brackets, that stills cost a lot.

I'm absolutly thinks this is a serious issue, but I'm not sure of what todo with it, hance the absence of PR.

  • brackets are they really necessary for packages and services? (edit answer: it ONLY ensure that the file / dir is optional. On an app that is older than one day, I'm sure of the structure that I use, and it should be totally recommended in perf reco to update that Kernel stuff to be exact and don't let it guess.)
  • should we purpose a better implementation on that hot path than the symfony/finder one. @nicolas-grekas purpose to "we could have some logic that splits a single glob-with-braces into several of them" Simplify the default Kernel recipes#705 (comment)

Metadata

Metadata

Assignees

No one assigned

    Labels

    ConfigHelp wantedIssues and PRs which are looking for volunteers to complete them.Issues and PRs which are looking for volunteers to complete them.Performance

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.