Skip to content
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

Improve performance of array_find() etc #18157

Merged
merged 2 commits into from
Mar 27, 2025
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions ext/standard/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -6597,7 +6597,7 @@ enum php_array_find_result {
PHP_ARRAY_FIND_SOME = 1,
};

static enum php_array_find_result php_array_find(const HashTable *array, zend_fcall_info fci, zend_fcall_info_cache fci_cache, zval *result_key, zval *result_value, bool negate_condition)
static enum php_array_find_result php_array_find(const HashTable *array, zend_fcall_info fci, zend_fcall_info_cache *fci_cache, zval *result_key, zval *result_value, bool negate_condition)
{
zend_ulong num_key;
zend_string *str_key;
Expand All @@ -6620,23 +6620,32 @@ static enum php_array_find_result php_array_find(const HashTable *array, zend_fc
if (!str_key) {
ZVAL_LONG(&args[1], num_key);
} else {
ZEND_ASSUME(!HT_IS_PACKED(array));
Copy link
Member

Choose a reason for hiding this comment

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

This could benefit from a short explanatory comment.

Copy link
Member

Choose a reason for hiding this comment

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

Ack. It's also not clear to me how this improves performance.

ZVAL_STR(&args[1], str_key);
}

ZVAL_COPY_VALUE(&args[0], operand);

zend_result result = zend_call_function(&fci, &fci_cache);
zend_result result = zend_call_function(&fci, fci_cache);
ZEND_ASSERT(result == SUCCESS);

if (UNEXPECTED(Z_ISUNDEF(retval))) {
return PHP_ARRAY_FIND_EXCEPTION;
}

bool retval_true = zend_is_true(&retval);
zval_ptr_dtor(&retval);

/* This negates the condition, if negate_condition is true. Otherwise it does nothing with `retval_true`. */
retval_true ^= negate_condition;
bool retval_true;
switch (Z_TYPE(retval)) {
case IS_TRUE:
retval_true = !negate_condition;
break;
case IS_FALSE:
retval_true = negate_condition;
break;
default:
retval_true = zend_is_true(&retval) ^ negate_condition;
zval_ptr_dtor(&retval);
break;
}
Copy link
Member

Choose a reason for hiding this comment

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

This can probably also apply to array_filter(). Perhaps this logic can be moved into some force-inlined:

	bool is_true(zval *retval, bool negate_condition) {
		switch (Z_TYPE(retval)) {
			case IS_TRUE:
				return !negate_condition;
			case IS_FALSE:
				return negate_condition;
			default:
				bool retval_true = zend_is_true(&retval) ^ negate_condition;
				zval_ptr_dtor(&retval);
				return retval_true;
		}
	}

that is then used for array_find and array_filter.


if (retval_true) {
if (result_value != NULL) {
Expand Down Expand Up @@ -6667,7 +6676,7 @@ PHP_FUNCTION(array_find)
Z_PARAM_FUNC(fci, fci_cache)
ZEND_PARSE_PARAMETERS_END();

php_array_find(array, fci, fci_cache, NULL, return_value, false);
php_array_find(array, fci, &fci_cache, NULL, return_value, false);
}
/* }}} */

Expand All @@ -6683,7 +6692,7 @@ PHP_FUNCTION(array_find_key)
Z_PARAM_FUNC(fci, fci_cache)
ZEND_PARSE_PARAMETERS_END();

php_array_find(array, fci, fci_cache, return_value, NULL, false);
php_array_find(array, fci, &fci_cache, return_value, NULL, false);
}
/* }}} */

Expand All @@ -6699,7 +6708,7 @@ PHP_FUNCTION(array_any)
Z_PARAM_FUNC(fci, fci_cache)
ZEND_PARSE_PARAMETERS_END();

RETURN_BOOL(php_array_find(array, fci, fci_cache, NULL, NULL, false) == PHP_ARRAY_FIND_SOME);
RETURN_BOOL(php_array_find(array, fci, &fci_cache, NULL, NULL, false) == PHP_ARRAY_FIND_SOME);
}
/* }}} */

Expand All @@ -6715,7 +6724,7 @@ PHP_FUNCTION(array_all)
Z_PARAM_FUNC(fci, fci_cache)
ZEND_PARSE_PARAMETERS_END();

RETURN_BOOL(php_array_find(array, fci, fci_cache, NULL, NULL, true) == PHP_ARRAY_FIND_NONE);
RETURN_BOOL(php_array_find(array, fci, &fci_cache, NULL, NULL, true) == PHP_ARRAY_FIND_NONE);
}
/* }}} */

Expand Down
Loading