]> granicus.if.org Git - git/commitdiff
hashcmp: use memcmp instead of open-coded loop
authorJeff King <peff@peff.net>
Wed, 9 Aug 2017 10:16:45 +0000 (06:16 -0400)
committerJunio C Hamano <gitster@pobox.com>
Wed, 9 Aug 2017 18:03:25 +0000 (11:03 -0700)
In 1a812f3a70 (hashcmp(): inline memcmp() by hand to
optimize, 2011-04-28), it was reported that an open-coded
loop outperformed memcmp() for comparing sha1s.

Discussion[1] a few years later in 2013 showed that this
depends on your libc's version of memcmp(). In particular,
glibc 2.13 optimized their memcmp around 2011. Here are
current timings with glibc 2.24 (best-of-five, on
linux.git):

  [before this patch, open-coded]
  $ time git rev-list --objects --all
  real 0m35.357s
  user 0m35.016s
  sys 0m0.340s

  [after this patch, memcmp]
  real 0m32.930s
  user 0m32.630s
  sys 0m0.300s

Now that we've had 6 years for that version of glibc to
make its way onto people's machines, it's worth revisiting
our benchmarks and switching to memcmp().

It may be that there are other non-glibc systems where
memcmp() isn't as well optimized. But since our single data
point in favor of open-coding was on a now-ancient glibc, we
should probably assume the system memcmp is good unless
proven otherwise. We may end up with a SLOW_MEMCMP Makefile
knob, but we can hold off on that until we actually find
such a system in practice.

[1] https://public-inbox.org/git/20130318073229.GA5551@sigill.intra.peff.net/

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
cache.h

diff --git a/cache.h b/cache.h
index 900796c155be49d8c275c735edf1c7a2dabec70a..5688b263e4658dd69cd2ca799bbf13d58be39a42 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -962,14 +962,7 @@ extern const struct object_id null_oid;
 
 static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2)
 {
-       int i;
-
-       for (i = 0; i < GIT_SHA1_RAWSZ; i++, sha1++, sha2++) {
-               if (*sha1 != *sha2)
-                       return *sha1 - *sha2;
-       }
-
-       return 0;
+       return memcmp(sha1, sha2, GIT_SHA1_RAWSZ);
 }
 
 static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)