Make WordPress Core


Ignore:
Timestamp:
06/18/2026 05:49:04 PM (10 hours ago)
Author:
dmsnell
Message:

Performance: avoid over-allocation in wp_is_numeric_array()

When a trace of allocations revealed that wp_is_numeric_array()
accounted for a significant fraction of the allocations in a page
render, it was observed that the function eagerly allocates and copies
array keys and then filters them when all it wants to know is whether a
single key in the array meets a condition.

In this patch the array_filter( array_keys() ) invocation is replaced
with early-aborting iteration to avoid the memory allocation and
copying.

This patch was prepared as part of WCEU 2026 Contributor Day.

Developed in: https://github.com/WordPress/wordpress-develop/pull/12100
Discussed in: https://core.trac.wordpress.org/ticket/65467

Follow-up to [34927].

Props dmsnell, westonruter, yusufmudagal.
Fixes #65467.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/functions.php

    r62521 r62524  
    52915291 * Determines if the variable is a numeric-indexed array.
    52925292 *
     5293 * Note! This answers a different question than {@see array_is_list()} and is
     5294 *       more flexible to handle situations where some numeric array indices
     5295 *       have been removed. A numeric-indexed array is only a “list” when the
     5296 *       array keys form a contiguous range from zero to the highest key.
     5297 *
     5298 * Example:
     5299 *
     5300 *     true  === wp_is_numeric_array( array( 1, 2, 3, 4 ) );
     5301 *     false === wp_is_numeric_array( array( 'name' => 'WordPress' ) );
     5302 *
     5303 *     // All-numeric keys vs. list.
     5304 *     $above_two   = array_filter( array( 1, 2, 8, 9 ), fn ( $v ) => $v > 2 );
     5305 *     $above_two === array( '2' => 8, '3' => 9 );
     5306 *     true       === wp_is_numeric_array( $above_two );
     5307 *     false      === array_is_list( $above_two );
     5308 *
    52935309 * @since 4.4.0
    52945310 *
    52955311 * @param mixed $data Variable to check.
    52965312 * @return bool Whether the variable is a list.
    5297  */
    5298 function wp_is_numeric_array( $data ) {
     5313 *
     5314 * @phpstan-assert-if-true array<int, mixed> $data
     5315 */
     5316function wp_is_numeric_array( $data ): bool {
    52995317    if ( ! is_array( $data ) ) {
    53005318        return false;
    53015319    }
    53025320
    5303     $keys        = array_keys( $data );
    5304     $string_keys = array_filter( $keys, 'is_string' );
    5305 
    5306     return count( $string_keys ) === 0;
     5321    foreach ( $data as $key => $value ) {
     5322        if ( is_string( $key ) ) {
     5323            return false;
     5324        }
     5325    }
     5326
     5327    return true;
    53075328}
    53085329
Note: See TracChangeset for help on using the changeset viewer.