Skip to content

Commit 107ae86

Browse files
committed
Introduce specialized functions to compare with integer and string, to eliminate repeatable checks on each loop iteration in in_array() function.
1 parent 37466b0 commit 107ae86

File tree

2 files changed

+74
-11
lines changed

2 files changed

+74
-11
lines changed

Zend/zend_operators.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,36 @@ static zend_always_inline int fast_equal_check_function(zval *op1, zval *op2)
913913
return Z_LVAL(result) == 0;
914914
}
915915

916+
static zend_always_inline int fast_equal_check_long(zval *op1, zval *op2)
917+
{
918+
zval result;
919+
if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
920+
return Z_LVAL_P(op1) == Z_LVAL_P(op2);
921+
}
922+
compare_function(&result, op1, op2);
923+
return Z_LVAL(result) == 0;
924+
}
925+
926+
static zend_always_inline int fast_equal_check_string(zval *op1, zval *op2)
927+
{
928+
zval result;
929+
if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
930+
if (Z_STR_P(op1) == Z_STR_P(op2)) {
931+
return 1;
932+
} else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
933+
if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
934+
return 0;
935+
} else {
936+
return memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0;
937+
}
938+
} else {
939+
return zendi_smart_strcmp(op1, op2) == 0;
940+
}
941+
}
942+
compare_function(&result, op1, op2);
943+
return Z_LVAL(result) == 0;
944+
}
945+
916946
static zend_always_inline void fast_equal_function(zval *result, zval *op1, zval *op2)
917947
{
918948
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {

ext/standard/array.c

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,20 +1273,53 @@ static inline void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior)
12731273
}
12741274
} ZEND_HASH_FOREACH_END();
12751275
} else {
1276-
ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_idx, str_idx, entry) {
1277-
if (fast_equal_check_function(value, entry)) {
1278-
if (behavior == 0) {
1279-
RETURN_TRUE;
1280-
} else {
1281-
if (str_idx) {
1282-
RETVAL_STR(zend_string_copy(str_idx));
1276+
ZVAL_DEREF(value);
1277+
if (Z_TYPE_P(value) == IS_LONG) {
1278+
ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_idx, str_idx, entry) {
1279+
if (fast_equal_check_long(value, entry)) {
1280+
if (behavior == 0) {
1281+
RETURN_TRUE;
12831282
} else {
1284-
RETVAL_LONG(num_idx);
1283+
if (str_idx) {
1284+
RETVAL_STR(zend_string_copy(str_idx));
1285+
} else {
1286+
RETVAL_LONG(num_idx);
1287+
}
1288+
return;
12851289
}
1286-
return;
12871290
}
1288-
}
1289-
} ZEND_HASH_FOREACH_END();
1291+
} ZEND_HASH_FOREACH_END();
1292+
} else if (Z_TYPE_P(value) == IS_STRING) {
1293+
ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_idx, str_idx, entry) {
1294+
if (fast_equal_check_string(value, entry)) {
1295+
if (behavior == 0) {
1296+
RETURN_TRUE;
1297+
} else {
1298+
if (str_idx) {
1299+
RETVAL_STR(zend_string_copy(str_idx));
1300+
} else {
1301+
RETVAL_LONG(num_idx);
1302+
}
1303+
return;
1304+
}
1305+
}
1306+
} ZEND_HASH_FOREACH_END();
1307+
} else {
1308+
ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_idx, str_idx, entry) {
1309+
if (fast_equal_check_function(value, entry)) {
1310+
if (behavior == 0) {
1311+
RETURN_TRUE;
1312+
} else {
1313+
if (str_idx) {
1314+
RETVAL_STR(zend_string_copy(str_idx));
1315+
} else {
1316+
RETVAL_LONG(num_idx);
1317+
}
1318+
return;
1319+
}
1320+
}
1321+
} ZEND_HASH_FOREACH_END();
1322+
}
12901323
}
12911324

12921325
RETURN_FALSE;

0 commit comments

Comments
 (0)