]> granicus.if.org Git - libass/commitdiff
Unroll FNV-1A hash function
authorGrigori Goronzy <greg@chown.ath.cx>
Wed, 29 Jan 2014 04:25:40 +0000 (05:25 +0100)
committerGrigori Goronzy <greg@chown.ath.cx>
Wed, 29 Jan 2014 04:27:29 +0000 (05:27 +0100)
Unroll the hash function with Duff's device for improved performance.

libass/ass_utils.h

index 6d795f0012877b13af5b6e5702f0c1ab0eb1eb59..4e2ba6c3a58bb85693a5b6a0821adbfc55e0e581 100644 (file)
@@ -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)