Skip to content

Commit cd62a6b

Browse files
authored
Merge pull request #23 from Nicoshev/rapidhashV2.2
Upgrade to V2.2 Improves speed by about 10% for sizes less than 4. Introduces RAPIDHASH_SUPER_COMPACT. This macro will further reduce code size, at the expense of reducing speed for sizes >= 96.
2 parents fed3ce2 + 50aca11 commit cd62a6b

File tree

1 file changed

+25
-20
lines changed

1 file changed

+25
-20
lines changed

rapidhash.h

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* rapidhash V2.1 - Very fast, high quality, platform-independent hashing algorithm.
2+
* rapidhash V2.2 - Very fast, high quality, platform-independent hashing algorithm.
33
* Copyright (C) 2025 Nicolas De Carli
44
*
55
* Based on 'wyhash', by Wang Yi <godspeed_china@yeah.net>
@@ -57,7 +57,6 @@
5757
# define RAPIDHASH_ALWAYS_INLINE inline
5858
#endif
5959

60-
6160
#ifdef __cplusplus
6261
# define RAPIDHASH_NOEXCEPT noexcept
6362
# define RAPIDHASH_CONSTEXPR constexpr
@@ -78,15 +77,24 @@
7877
* Small input speed macro, improves small input speed at the expense of sacrificing large input speed.
7978
*
8079
* RAPIDHASH_UNROLLED: Normal behavior, max large input speed.
81-
* RAPIDHASH_COMPACT: Improved small input speed.
80+
* RAPIDHASH_COMPACT: Improved small input speed and reduced code size.
81+
*
82+
* RAPIDHASH_SUPER_COMPACT: Almost always decreases speed for sizes > 95, but will further reduce code size.
8283
*/
84+
#ifdef RAPIDHASH_SUPER_COMPACT
85+
# ifndef RAPIDHASH_COMPACT
86+
# define RAPIDHASH_COMPACT
87+
# endif
88+
#endif
8389
#ifndef RAPIDHASH_COMPACT
8490
# define RAPIDHASH_UNROLLED
8591
# define RAPIDHASH_UNLIKELY_BULK(x) _unlikely_(x)
92+
# define RAPIDHASH_LIKELY_BULK(x) _likely_(x)
8693
#elif defined(RAPIDHASH_UNROLLED)
8794
# error "cannot define RAPIDHASH_COMPACT and RAPIDHASH_UNROLLED simultaneously."
8895
#else
8996
# define RAPIDHASH_UNLIKELY_BULK(x) (x)
97+
# define RAPIDHASH_LIKELY_BULK(x) (x)
9098
#endif
9199

92100
/*
@@ -230,18 +238,6 @@
230238
}
231239
#endif
232240

233-
/*
234-
* Reads and combines 3 bytes of input.
235-
*
236-
* @param p Buffer to read from.
237-
* @param k Length of @p, in bytes.
238-
*
239-
* Always reads and combines 3 bytes from memory.
240-
* Guarantees to read each buffer position at least once.
241-
*
242-
* Returns a 64-bit value containing all three bytes read.
243-
*/
244-
RAPIDHASH_INLINE_CONSTEXPR uint64_t rapid_readSmall(const uint8_t *p, size_t k) RAPIDHASH_NOEXCEPT { return (((uint64_t)p[0])<<56)|(((uint64_t)p[k>>1])<<32)|p[k-1];}
245241
/*
246242
* rapidhash main function.
247243
*
@@ -268,11 +264,11 @@ RAPIDHASH_INLINE_CONSTEXPR uint64_t rapidhash_internal(const void *key, size_t l
268264
b = rapid_read32(plast);
269265
}
270266
} else if (_likely_(len > 0)) {
271-
a = rapid_readSmall(p, len);
272-
b = 0;
267+
a = (((uint64_t)p[0])<<56)|p[len-1];
268+
b = p[len>>1];
273269
} else
274270
a = b = 0;
275-
} else if (_likely_(len <= 64)) {
271+
} else if (len <= 64) {
276272
seed = rapid_mix(rapid_read64(p) ^ secret[0], rapid_read64(p + 8) ^ seed);
277273
if (len > 32) {
278274
seed = rapid_mix(rapid_read64(p + 16) ^ secret[1], rapid_read64(p + 24) ^ seed);
@@ -329,6 +325,7 @@ RAPIDHASH_INLINE_CONSTEXPR uint64_t rapidhash_internal(const void *key, size_t l
329325
i -= 112;
330326
}
331327
#endif
328+
#ifndef RAPIDHASH_SUPER_COMPACT
332329
if (_likely_(i >= 48)) {
333330
seed = rapid_mix(rapid_read64(p) ^ secret[0], rapid_read64(p + 8) ^ seed);
334331
see1 = rapid_mix(rapid_read64(p + 16) ^ secret[1], rapid_read64(p + 24) ^ see1);
@@ -343,13 +340,22 @@ RAPIDHASH_INLINE_CONSTEXPR uint64_t rapidhash_internal(const void *key, size_t l
343340
i -= 48;
344341
}
345342
}
343+
#else
344+
while (_likely_(i >= 48)) {
345+
seed = rapid_mix(rapid_read64(p) ^ secret[0], rapid_read64(p + 8) ^ seed);
346+
see1 = rapid_mix(rapid_read64(p + 16) ^ secret[1], rapid_read64(p + 24) ^ see1);
347+
see2 = rapid_mix(rapid_read64(p + 32) ^ secret[2], rapid_read64(p + 40) ^ see2);
348+
p += 48;
349+
i -= 48;
350+
}
351+
#endif
346352
see3 ^= see4;
347353
see5 ^= see6;
348354
seed ^= see1;
349355
see3 ^= see2;
350356
seed ^= see5;
351357
seed ^= see3;
352-
if ((i > 16)) {
358+
if (i > 16) {
353359
seed = rapid_mix(rapid_read64(p) ^ secret[2], rapid_read64(p + 8) ^ seed);
354360
if (RAPIDHASH_UNLIKELY_BULK(i > 32))
355361
seed = rapid_mix(rapid_read64(p + 16) ^ secret[2], rapid_read64(p + 24) ^ seed);
@@ -390,4 +396,3 @@ RAPIDHASH_INLINE_CONSTEXPR uint64_t rapidhash_withSeed(const void *key, size_t l
390396
RAPIDHASH_INLINE_CONSTEXPR uint64_t rapidhash(const void *key, size_t len) RAPIDHASH_NOEXCEPT {
391397
return rapidhash_withSeed(key, len, 0);
392398
}
393-

0 commit comments

Comments
 (0)