Skip to content

Avoid unnecessary calls to strtolower(). #14558

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

Closed
wants to merge 2 commits into from

Conversation

catch56
Copy link

@catch56 catch56 commented May 5, 2015

DependencyInjection - remove unnecessary calls to strtolower()

I noticed when profiling Drupal 8, that each service requested via container::get() requires a strtolower() call. This was previously saved for multiple calls to the same service with e4b3039, but we can also avoid the initial call too but slightly re-organising the code. Most of the diff is indentation.

Drupal.org issue here which shows the (very modest, about 0.5ms in my profiling) performance improvement: https://www.drupal.org/node/2480943

Q A
Bug fix? [yes
New feature? [no]
BC breaks? [no]
Deprecations? [no]
Tests pass? [yes
Fixed tickets []
License MIT
Doc PR []

@catch56 catch56 force-pushed the strtolower_again branch from ee4d0c3 to 85f9618 Compare May 5, 2015 12:01
@Tobion
Copy link
Contributor

Tobion commented May 5, 2015

Related to #14470 and #14211

@catch56 catch56 force-pushed the strtolower_again branch from 31f17b8 to 85f9618 Compare May 5, 2015 13:05
if ($strtolower) {
return;
}
else {
Copy link
Contributor

Choose a reason for hiding this comment

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

must be } else {

Copy link
Contributor

Choose a reason for hiding this comment

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

I think that it should be.

if ($strtolower && self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) {
    // code
} else if ($strtolower) {
    return;
} else {
    continue;
}

@dosten
Copy link
Contributor

dosten commented May 5, 2015

How many service call you tested?

@catch56
Copy link
Author

catch56 commented May 5, 2015

So this cut 190 calls to strtolower() - i.e. Container::get() was called with a different service name 190 times during the request. Actual usage on real sites may well end up being higher.

@dosten
Copy link
Contributor

dosten commented May 5, 2015

But the strtolower call is not executed in all Container::get() calls, only if i define a foo service and i try to get it with Container::get('FOO'), your test covers this?

@dawehner
Copy link
Contributor

dawehner commented May 5, 2015

@dosten
Well, in case the service is not initialised yet, which have been the case 190 times in the test of @catch56 then you end up going throw both FALSE and TRUE in the foreach().

@dosten
Copy link
Contributor

dosten commented May 5, 2015

@dawehner you're right 👍

@dosten
Copy link
Contributor

dosten commented May 5, 2015

I think this can be merged in 2.3

}

throw new ServiceNotFoundException($id, null, null, $alternatives);
} else if ($strtolower) {
Copy link
Contributor

Choose a reason for hiding this comment

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

elseif (no space)

@fabpot
Copy link
Member

fabpot commented May 7, 2015

should be merged in 2.7.

@Tobion
Copy link
Contributor

Tobion commented May 7, 2015

So we save a strtolower call, but on the other the following code is executed twice or am I missing something?

if (isset($this->methodMap[$id])) {
                $method = $this->methodMap[$id];
} elseif (method_exists($this, $method = 'get'.strtr($id, array('_' => '', '.' => '_', '\\' => '_')).'Service')) {

So what is the actual net gain?

@catch56
Copy link
Author

catch56 commented May 11, 2015

That only gets run twice if the loop doesn't return before (i.e. no match without the normalisation).

@stof
Copy link
Member

stof commented May 11, 2015

@Tobion there is an issue here: if the id passed in the method is not lowercased, the service will be built again, replacing the previous instance. This introduces a bug. This is precisely why the normalized version of the id is checked in instantiated services before going through the creation logic.

so 👎 for this PR. It is broken for dumped containers (method names in PHP are case insensitive, so it will find the dumped factory method). The logic works fine for the ContainerBuilder because the Definition lookup is case sensitive in this case.

@nicolas-grekas
Copy link
Member

See #14643

fabpot added a commit that referenced this pull request May 28, 2015
…wer() (nicolas-grekas)

This PR was merged into the 2.3 branch.

Discussion
----------

[DependencyInjection] Avoid unnecessary calls to strtolower()

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #14558
| License       | MIT
| Doc PR        | -

Commits
-------

c27f564 [DependencyInjection] Avoid unnecessary calls to strtolower()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants