]> granicus.if.org Git - php/commitdiff
Optimize zend_hash_find() for the most usual case
authorDmitry Stogov <dmitry@zend.com>
Mon, 7 May 2018 12:18:02 +0000 (15:18 +0300)
committerDmitry Stogov <dmitry@zend.com>
Mon, 7 May 2018 12:18:02 +0000 (15:18 +0300)
Zend/zend_hash.c

index 1d6519e51991bd6051b8eae7cefcdc216abaf77b..ca1e7d69640fe66627956eddaa5f4d0ef7b85216 100644 (file)
@@ -554,18 +554,30 @@ static zend_always_inline Bucket *zend_hash_find_bucket(const HashTable *ht, zen
        arData = ht->arData;
        nIndex = h | ht->nTableMask;
        idx = HT_HASH_EX(arData, nIndex);
-       while (EXPECTED(idx != HT_INVALID_IDX)) {
-               p = HT_HASH_TO_BUCKET_EX(arData, idx);
-               if (EXPECTED(p->key == key)) { /* check for the same interned string */
-                       return p;
-               } else if (EXPECTED(p->h == ZSTR_H(key)) &&
-                    EXPECTED(p->key) &&
-                    EXPECTED(zend_string_equal_content(p->key, key))) {
+
+       if (UNEXPECTED(idx == HT_INVALID_IDX)) {
+               return NULL;
+       }
+       p = HT_HASH_TO_BUCKET_EX(arData, idx);
+       if (EXPECTED(p->key == key)) { /* check for the same interned string */
+               return p;
+       }
+
+       while (1) {
+               if (p->h == ZSTR_H(key) &&
+                   EXPECTED(p->key) &&
+                   zend_string_equal_content(p->key, key)) {
                        return p;
                }
                idx = Z_NEXT(p->val);
+               if (idx == HT_INVALID_IDX) {
+                       return NULL;
+               }
+               p = HT_HASH_TO_BUCKET_EX(arData, idx);
+               if (p->key == key) { /* check for the same interned string */
+                       return p;
+               }
        }
-       return NULL;
 }
 
 static zend_always_inline Bucket *zend_hash_str_find_bucket(const HashTable *ht, const char *str, size_t len, zend_ulong h)