Problem/Motivation

At DrupalCon Nashville, a presentation on Symfony 4 PHP performance improvements included a discussion of the OPcache compilation process and the relatively easy/straightforward changes Symfony made in commonly-used classes to benefit from this. (These upstream optimizations have already landed in Drupal as part of Symfony 3.4.)

In a nutshell, OPcache will better optimize calls to native PHP functions like is_array() within namespaced code only if root-namespace prefixed, e.g., \is_array(), because at runtime the non-namespaced, non-native variant may exist. This is not commonly done by developers at the moment, though the Drupal coding standards do not appear to specifically preclude it, either:

Functions should be called with no spaces between the function name, the opening parenthesis, and the first parameter; spaces between commas and each parameter, and no space between the last parameter, the closing parenthesis, and the semicolon. Here's an example:

I have not yet profiled the improvements that Drupal may see from such refactoring, but given Symfony's (and others, based on the GitHub inbound issue mentions) adoption of this pattern, I would imagine it is more than negligible.

Proposed resolution

Apply a targeted application of this pattern and (potentially?) encourage it by way of the coding standards or other documentation.

Remaining tasks

Get buy-in from core committers and profile performance improvements.

User interface changes

None.

API changes

None.

Data model changes

None.

Issue fork drupal-2960522

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

bradjones1 created an issue. See original summary.

bradjones1’s picture

FileSize
545.32 KB

Attached is a POC patch generated with:

vendor/bin/php-cs-fixer fix lib --rules='{"native_function_invocation":{"opcache-only": true}}' --allow-risky=yes

(requires the option added in this PR)

bradjones1’s picture

Ack, I screwed up the prefixes and suffixes on the git diff.

cilefen’s picture

We should do this provided we can measure improvements and implement an automated standards check.

bradjones1’s picture

@cilefen Are you at the sprints today in Nashville? Let's talk about the best plan of attack there? I am not an expert at profiling but I do have a Blackfire subscription and perhaps there's a way to run the core test suite with and without this type of patch and that would be sufficient? Or I'm not sure what other kind of more "real-world" profile might make more sense?

cilefen’s picture

I am not there. It's probably worth something on its own if it only improves test performance. But real use-cases are what we mainly want to see improving. I am on Slack.

amateescu’s picture

It would probably make sense to do these changes only in the files that are in the hot path of a request, before any caching kicks in, not everywhere across the board like the current patch does.

heddn’s picture

I'm queueing a test, but I want to say that namespacing these things will not work on php 5.5. I'm not sure though, so testing it.

heddn’s picture

Looks like I'm wrong. See https://3v4l.org/gdmrW. Seems like it was added in php 5.4.

dawehner’s picture

I think @amateescu's suggestion is great! I would easily imagine that the the result is kind of disappointing though.

bradjones1’s picture

It's certainly possible that either a) our specific implementation does not benefit much from this or b) the changes from Symfony along the same vein accomplished whatever optimization we might have otherwise obtained. Some initial testing with ab would indicate there's not much change, however I am going to have to devise a better profiling plan than just a bare-bones install with opcache installed, since in my local environment the requests are around 5 ms, which doesn't give much room for improvement, anyway. Ideas would be welcome.

dawehner’s picture

@bradjones1 I would suggest you to use maybe tools like xhprof or blackfire. They tend to show a better picture, especially in terms of understanding why something got faster.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

ever-c0de made their first commit to this issue’s fork.

ever-c0de’s picture

FileSize
86.36 KB

Hello, guys.

It's been a long time since the last comment so I decided to repeat the test.

I have tested difference between the default core and the prefixes appended to built-in functions.

I did the following setup:

  1. Fresh Drupal 9.3 with default Umami installation profile;
  2. Selected random page with some content;
  3. Added 20+ test comments ( with a big amount of text, some images and replies to comments ) to this page;
  4. Added several Drupal Views;

(idea was to have different components that should be rendered)

I used admin user and disabled all render cache.

Test before prefixes appended:
Only local images are allowed.
Link to the test.

Test after prefixes appended:
Only local images are allowed.
Link to the test.

We can compare those two tests:
Only local images are allowed.
Link.

The difference is in -4.0-5.1%.

In total I have made 3 tests:
First test.
Second test.
Third test.

To append prefixes to built-in functions I have used `php-cs-fixer` with this command:
vendor/bin/php-cs-fixer fix core --rules='{"native_function_invocation":{"scope": namespaced}}' --allow-risky=yes (it has changed since comment #2)

Matroskeen’s picture

Issue tags: +LutskCodeSprint2021

We were working on this during our local code sprint event, so adding a tag :)

Matroskeen’s picture

Status: Active » Needs work

At a glance, numbers are promising, but it would be great to run more tests.
I think they might be similar to those performed by @Berdir here: #2407187-38: Optimize LibraryDependencyResolver::getMinimalRepresentativeSubset() and win >=4%.

Also, one test is failing, so I'm moving to NW at this moment.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.