From: Dmitry Stogov Date: Sat, 27 Dec 2014 08:11:40 +0000 (+0300) Subject: Introduce specialized functions to compare with integer and string, to eliminate... X-Git-Tag: PRE_PHP7_REMOVALS~35^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=107ae86ca6baf2b79d8ddb32b54676a28269ba1f;p=php Introduce specialized functions to compare with integer and string, to eliminate repeatable checks on each loop iteration in in_array() function. --- diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index 1426fe919a..20f8ccd32c 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -913,6 +913,36 @@ static zend_always_inline int fast_equal_check_function(zval *op1, zval *op2) return Z_LVAL(result) == 0; } +static zend_always_inline int fast_equal_check_long(zval *op1, zval *op2) +{ + zval result; + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + return Z_LVAL_P(op1) == Z_LVAL_P(op2); + } + compare_function(&result, op1, op2); + return Z_LVAL(result) == 0; +} + +static zend_always_inline int fast_equal_check_string(zval *op1, zval *op2) +{ + zval result; + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + if (Z_STR_P(op1) == Z_STR_P(op2)) { + return 1; + } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { + if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { + return 0; + } else { + return memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0; + } + } else { + return zendi_smart_strcmp(op1, op2) == 0; + } + } + compare_function(&result, op1, op2); + return Z_LVAL(result) == 0; +} + static zend_always_inline void fast_equal_function(zval *result, zval *op1, zval *op2) { if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { diff --git a/ext/standard/array.c b/ext/standard/array.c index 410ff21b9a..2ae3119549 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -1273,20 +1273,53 @@ static inline void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior) } } ZEND_HASH_FOREACH_END(); } else { - ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_idx, str_idx, entry) { - if (fast_equal_check_function(value, entry)) { - if (behavior == 0) { - RETURN_TRUE; - } else { - if (str_idx) { - RETVAL_STR(zend_string_copy(str_idx)); + ZVAL_DEREF(value); + if (Z_TYPE_P(value) == IS_LONG) { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_idx, str_idx, entry) { + if (fast_equal_check_long(value, entry)) { + if (behavior == 0) { + RETURN_TRUE; } else { - RETVAL_LONG(num_idx); + if (str_idx) { + RETVAL_STR(zend_string_copy(str_idx)); + } else { + RETVAL_LONG(num_idx); + } + return; } - return; } - } - } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); + } else if (Z_TYPE_P(value) == IS_STRING) { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_idx, str_idx, entry) { + if (fast_equal_check_string(value, entry)) { + if (behavior == 0) { + RETURN_TRUE; + } else { + if (str_idx) { + RETVAL_STR(zend_string_copy(str_idx)); + } else { + RETVAL_LONG(num_idx); + } + return; + } + } + } ZEND_HASH_FOREACH_END(); + } else { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_idx, str_idx, entry) { + if (fast_equal_check_function(value, entry)) { + if (behavior == 0) { + RETURN_TRUE; + } else { + if (str_idx) { + RETVAL_STR(zend_string_copy(str_idx)); + } else { + RETVAL_LONG(num_idx); + } + return; + } + } + } ZEND_HASH_FOREACH_END(); + } } RETURN_FALSE;