]> granicus.if.org Git - php/commitdiff
micro optimized initial hash size calculation
authorAnatol Belski <ab@php.net>
Wed, 22 Oct 2014 13:28:54 +0000 (15:28 +0200)
committerAnatol Belski <ab@php.net>
Wed, 22 Oct 2014 15:56:24 +0000 (17:56 +0200)
most of the calls are with a size <= 8, so don't even bother any
bitshifts. For the bigger sizes, use an intrinsic (should be extended
with gcc ones though).

Zend/zend_hash.c

index dfd63aa7e196f3bb08db6b3a84e87c4760180ca5..d3423c842f7ae4ad822725e00b8f8b48681f784d 100644 (file)
@@ -99,7 +99,6 @@ static const uint32_t uninitialized_bucket = {INVALID_IDX};
 
 ZEND_API void _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC)
 {
-       uint32_t i = 3;
 
        SET_INCONSISTENT(HT_OK);
 
@@ -107,10 +106,23 @@ ZEND_API void _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestru
                /* prevent overflow */
                ht->nTableSize = 0x80000000;
        } else {
-               while ((1U << i) < nSize) {
-                       i++;
+               if (nSize > 8) {
+#ifdef PHP_WIN32
+                       ht->nTableSize = 1U << __lzcnt(nSize);
+                       if (ht->nTableSize < nSize) {
+                               ht->nTableSize <<= 1;
+                       }
+#else
+                       uint32_t i = 4;
+
+                       while ((1U << i) < nSize) {
+                               i++;
+                       }
+                       ht->nTableSize = 1 << i;
+#endif
+               } else {
+                       ht->nTableSize = 8;
                }
-               ht->nTableSize = 1 << i;
        }
 
        ht->nTableMask = 0;     /* 0 means that ht->arBuckets is uninitialized */