summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrigori Goronzy <greg@chown.ath.cx>2014-01-29 05:25:40 +0100
committerGrigori Goronzy <greg@chown.ath.cx>2014-01-29 05:27:29 +0100
commitf466b9678b4b68e56d7374dea51218348d628b06 (patch)
tree3e130afc1a9ff88d32fb826549afdb4b0a9e1344
parent8adee493913fbf21c285f15717270757e87b4779 (diff)
downloadlibass-f466b9678b4b68e56d7374dea51218348d628b06.tar.bz2
libass-f466b9678b4b68e56d7374dea51218348d628b06.tar.xz
Unroll FNV-1A hash function
Unroll the hash function with Duff's device for improved performance.
-rw-r--r--libass/ass_utils.h13
1 files changed, 9 insertions, 4 deletions
diff --git a/libass/ass_utils.h b/libass/ass_utils.h
index 6d795f0..4e2ba6c 100644
--- a/libass/ass_utils.h
+++ b/libass/ass_utils.h
@@ -132,11 +132,16 @@ static inline int rot_key(double a)
static inline unsigned fnv_32a_buf(void *buf, size_t len, unsigned hval)
{
unsigned char *bp = buf;
- unsigned char *be = bp + len;
- while (bp < be) {
- hval ^= (unsigned) *bp++;
- hval *= FNV1_32A_PRIME;
+ size_t n = (len + 3) / 4;
+
+ switch (len % 4) {
+ case 0: do { hval ^= (unsigned) *bp++; hval *= FNV1_32A_PRIME;
+ case 3: hval ^= (unsigned) *bp++; hval *= FNV1_32A_PRIME;
+ case 2: hval ^= (unsigned) *bp++; hval *= FNV1_32A_PRIME;
+ case 1: hval ^= (unsigned) *bp++; hval *= FNV1_32A_PRIME;
+ } while (--n > 0);
}
+
return hval;
}
static inline unsigned fnv_32a_str(char *str, unsigned hval)