Skip to content
Permalink
Browse files

Merge branch 'PHP-7.4'

* PHP-7.4:
  Improve PHP hash function. See Daniel Lemire's blog post https://lemire.me/blog/2016/07/21/accelerating-php-hashing-by-unoptimizing-it/
  • Loading branch information...
dstogov committed May 8, 2019
2 parents 230d308 + 90e285f commit 370f4e4c6f26e5fa76dd0e2cd2bd0adcf9ca5ed4
Showing with 44 additions and 0 deletions.
  1. +44 −0 Zend/zend_string.h
@@ -361,6 +361,49 @@ static zend_always_inline zend_ulong zend_inline_hash_func(const char *str, size
{
zend_ulong hash = Z_UL(5381);

#if defined(_WIN32) || defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
/* Version with multiplication works better on modern CPU */
for (; len >= 8; len -= 8, str += 8) {
hash =
hash * 33 * 33 * 33 * 33 +
str[0] * 33 * 33 * 33 +
str[1] * 33 * 33 +
str[2] * 33 +
str[3];
hash =
hash * 33 * 33 * 33 * 33 +
str[4] * 33 * 33 * 33 +
str[5] * 33 * 33 +
str[6] * 33 +
str[7];
}
if (len >= 4) {
hash =
hash * 33 * 33 * 33 * 33 +
str[0] * 33 * 33 * 33 +
str[1] * 33 * 33 +
str[2] * 33 +
str[3];
len -= 4;
str += 4;
}
if (len >= 2) {
if (len > 2) {
hash =
hash * 33 * 33 * 33 +
str[0] * 33 * 33 +
str[1] * 33 +
str[2];
} else {
hash =
hash * 33 * 33 +
str[0] * 33 +
str[1];
}
} else if (len != 0) {
hash = hash * 33 + *str;
}
#else
/* variant with the hash unrolled eight times */
for (; len >= 8; len -= 8) {
hash = ((hash << 5) + hash) + *str++;
@@ -383,6 +426,7 @@ static zend_always_inline zend_ulong zend_inline_hash_func(const char *str, size
case 0: break;
EMPTY_SWITCH_DEFAULT_CASE()
}
#endif

/* Hash value can't be zero, so we always set the high bit */
#if SIZEOF_ZEND_LONG == 8

0 comments on commit 370f4e4

Please sign in to comment.
You can’t perform that action at this time.