Media, Editor, Menus: Use isset() instead of in_array() over array_keys() - #66
Closed
mukeshpanchal27 wants to merge 2 commits into
Closed
Media, Editor, Menus: Use isset() instead of in_array() over array_keys()#66mukeshpanchal27 wants to merge 2 commits into
mukeshpanchal27 wants to merge 2 commits into
Conversation
isset() instead of in_array() over array_key()
mukeshpanchal27
force-pushed
the
perf/in-array-array-keys
branch
from
August 7, 2026 05:45
977cc2a to
ff06256
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Nine call sites in core answer the question "does this array have this key?" the expensive way:
That is O(n) in time and O(n) in memory —
array_keys()allocates a brand new packed array of every key on each call, purely soin_array()can walk it and throw it away. PHP already indexes arrays by key in a hash table, so the same question is answerable in O(1):Changes
7 files, 9 call sites:
wp-includes/media.php$_wp_additional_image_sizesimage_constrain_size_for_editor()— runs per image, per size, on every editor/media request. Hottest of the nine.wp-includes/block-editor.php$image_size_nameswp-includes/sitemaps.php$provider->get_object_subtypes()get_sitemap_url().wp-includes/link-template.php$blogsget_dashboard_url()— every site a user belongs to, unbounded on large networks.wp-admin/includes/dashboard.phpget_blogs_of_user()wp-admin/includes/class-theme-installer-skin.php$all_themeswp-admin/nav-menus.php(×3)$dbids_to_ordersIn
media.phpthe accompanying! empty( $_wp_additional_image_sizes ) &&guard is dropped as redundant —isset()on a key of an empty or undefined array is alreadyfalse:Measurement
PHP 8.3.2, 200,000 iterations per case, key present at the last position (worst case for
in_array) and absent:in_array(array_keys())hitisset()hitin_array(array_keys())mississet()mississet()is flat at ~7 ms regardless of array size; the current form grows linearly. The per-call allocation is avoided entirely, which also takes pressure off the GC.Behaviour notes
Two differences between the old and new expressions, neither of which is a regression at any of these call sites:
isset()isfalsefor anullvalue. Every array here stores arrays, objects, strings or ints as values — nevernull. (array_key_exists()would be the literal equivalent, but it is measurably slower thanisset()and unnecessary here.)'2'toint 2on insertion, soin_array( '2', array_keys( $a ), true )returnsfalsefor a size registered as'2'whileisset( $a['2'] )correctly returnstrue. The new code is more correct; the old strict comparison was silently failing to match such keys. Innav-menus.phpthe needle is already explicitly cast with(int), so both forms agree.Testing instructions
vendor/bin/phpcs src/wp-includes/media.php src/wp-includes/block-editor.php src/wp-includes/sitemaps.php src/wp-includes/link-template.php src/wp-admin/includes/dashboard.php src/wp-admin/includes/class-theme-installer-skin.php src/wp-admin/nav-menus.phpadd_image_size()and check the constrained dimensions are unchanged.get_dashboard_url()still returns the site dashboard for a user who belongs to the current site, and the user dashboard for one who does not.Verification done
php -lclean on all 7 files.vendor/bin/phpcs: 0 errors. The 2 warnings emitted are pre-existingWordPress.DB.PreparedSQL.NotPreparednotices on unrelated lines (link-template.php:2030,media.php:5716).