]> granicus.if.org Git - php/commitdiff
Introduce specialized functions to compare with integer and string, to eliminate...
authorDmitry Stogov <dmitry@zend.com>
Sat, 27 Dec 2014 08:11:40 +0000 (11:11 +0300)
committerDmitry Stogov <dmitry@zend.com>
Sat, 27 Dec 2014 08:11:40 +0000 (11:11 +0300)
Zend/zend_operators.h
ext/standard/array.c

index 1426fe919af2af10dc4b01079677769fd03e95e1..20f8ccd32c4327aaceda05bd6b418f7bf713e223 100644 (file)
@@ -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)) {
index 410ff21b9adad8b9bc43a0fe4353428bfb0f72b3..2ae3119549aeefc34692ebf77d2fb8bb72e03d70 100644 (file)
@@ -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;