Plugins: Speed up hooks addition/removal by ~26%.#11865
Conversation
Replaces spl_object_hash() with spl_object_id() in _wp_filter_build_unique_id() and WP_Widget_Factory, adds an early return for plain object callbacks, removes the unreachable null return, and drops the stale falsey-key guard in has_filter(). Fixes https://core.trac.wordpress.org/ticket/58291
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
Co-authored-by: Weston Ruter <westonruter@gmail.com>
Co-authored-by: Weston Ruter <westonruter@gmail.com> Co-authored-by: Boro Sitnikovski <boro.sitnikovski@automattic.com>
Co-authored-by: Weston Ruter <westonruter@gmail.com>
…que_id(). The guard should return null for non-callable arrays, not for valid ones.
…_build_unique_id(). isset()+is_string() is ~22% faster while providing the same type safety guarantee that $callback[1] exists and is a string.
…th syntax_only. Replaces isset()+is_string() guard with is_callable( $callback, true ), which already guarantees $callback[0] is a string or object, removing the dead elseif branch and trailing return null.
… type. Narrows @param from callable|string|array to callable and fixes alignment, reflecting that invalid callback values are usage errors caught by static analysis, not valid input variants.
| return (string) spl_object_id( (object) $callback ); | ||
| } | ||
|
|
||
| $callback = (array) $callback; |
There was a problem hiding this comment.
Interestingly, I thought that this line could be removed, since above $callback is excluded from being a string or an object. The only other possible value which can be callable at this point is array, so this casting would seem to be redundant. But PHPStan doesn't currently do this narrowing. Without the cast, it is seen as: mixed~(object|string) and then the is_callable() narrows it it callable(): mixed: https://phpstan.org/r/577fd6d9-b6b9-4362-9acc-0794187fa71a
There was a problem hiding this comment.
I would have thought PHPStan would narrow it to non-empty-list<mixed>&callable() automatically.
westonruter
left a comment
There was a problem hiding this comment.
Thank you for the iterations!
|
Benchmark results of the PR in its current state; tested on After several iterations, I noticed that This is because they go through the new For completeness: - if ( ! is_callable( $callback, true ) ) {
+ if ( ! isset( $callback[1] ) || ! is_string( $callback[1] ) ) { |
Covers return type consistency (string), uniqueness between objects, stability for the same object, and null returns for malformed arrays. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…ble() with syntax_only." This reverts commit f6f6de7.
@bor0 It looks like I was wrong. After re-testing with I reverted back to what you had before in 6f23ca4, and this is now fixed. If we wanted to use if ( ! is_callable( $callback, true ) || ! is_string( $callback[1] ) ) {As I understand, what you had before was slightly more performant anyway, so I think it's a win-win. |
|
Via 541dc90 I also added a missing This check was present wordpress-develop/src/wp-includes/class-wp-hook.php Lines 198 to 202 in 0d0c832 It was also present in wordpress-develop/src/wp-includes/class-wp-hook.php Lines 245 to 249 in 0d0c832 But it was missing in |
|
Alright, thanks! Looks good 🙌 |
…of `spl_object_hash()` to construct unique IDs. * Also use `spl_object_id()` similarly when registering and unregistering classic widgets. * Improve typing and phpdoc in `_wp_filter_build_unique_id()`. Return `null` for malformed callbacks. * Add tests for `_wp_filter_build_unique_id()`. * Improve type safety of `WP_Hook::add_filter()` in case an invalid callback is provided for parity with `::has_filter()` and `::remove_filter()`. Developed in #11865 Follow-up to r46220, r46801, r60179. Props bor0, westonruter, SergeyBiryukov, schlessera, arshidkv12, knutsp, spacedmonkey, swissspidy. See #64898. Fixes #58291. git-svn-id: https://develop.svn.wordpress.org/trunk@62408 602fd350-edb4-49c9-b593-d223f7449a82
…of `spl_object_hash()` to construct unique IDs. * Also use `spl_object_id()` similarly when registering and unregistering classic widgets. * Improve typing and phpdoc in `_wp_filter_build_unique_id()`. Return `null` for malformed callbacks. * Add tests for `_wp_filter_build_unique_id()`. * Improve type safety of `WP_Hook::add_filter()` in case an invalid callback is provided for parity with `::has_filter()` and `::remove_filter()`. Developed in WordPress/wordpress-develop#11865 Follow-up to r46220, r46801, r60179. Props bor0, westonruter, SergeyBiryukov, schlessera, arshidkv12, knutsp, spacedmonkey, swissspidy. See #64898. Fixes #58291. Built from https://develop.svn.wordpress.org/trunk@62408 git-svn-id: http://core.svn.wordpress.org/trunk@61689 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Replaces spl_object_hash() with spl_object_id() in _wp_filter_build_unique_id() and WP_Widget_Factory, and adds an early return for plain object callbacks.
Fixes https://core.trac.wordpress.org/ticket/58291