changeset 7147:1388e7363d86

* memcoll.c (memcoll): Optimize for the common case where the arguments are bytewise equal.
author Paul Eggert <eggert@cs.ucla.edu>
date Tue, 15 Aug 2006 21:48:44 +0000
parents f0b6593e5fab
children 06ddea502cf5
files lib/ChangeLog lib/memcoll.c
diffstat 2 files changed, 41 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,8 @@
+2006-08-15  Paul Eggert  <eggert@cs.ucla.edu>
+
+	* memcoll.c (memcoll): Optimize for the common case where the
+	arguments are bytewise equal.
+
 2006-08-14  Paul Eggert  <eggert@cs.ucla.edu>
 
 	Change copyright notice from LGPL 2 to GPL 2, since that's the
--- a/lib/memcoll.c
+++ b/lib/memcoll.c
@@ -38,40 +38,49 @@
 
 #if HAVE_STRCOLL
 
-  char n1 = s1[s1len];
-  char n2 = s2[s2len];
+  /* strcoll is slow on many platforms, so check for the common case
+     where the arguments are bytewise equal.  Otherwise, walk through
+     the buffers using strcoll on each substring.  */
 
-  s1[s1len++] = '\0';
-  s2[s2len++] = '\0';
-
-  while (! (errno = 0, (diff = strcoll (s1, s2)) || errno))
+  if (s1len == s2len && memcmp (s1, s2, s1len) == 0)
+    diff = 0;
+  else
     {
-      /* strcoll found no difference, but perhaps it was fooled by NUL
-	 characters in the data.  Work around this problem by advancing
-	 past the NUL chars.  */
-      size_t size1 = strlen (s1) + 1;
-      size_t size2 = strlen (s2) + 1;
-      s1 += size1;
-      s2 += size2;
-      s1len -= size1;
-      s2len -= size2;
+      char n1 = s1[s1len];
+      char n2 = s2[s2len];
 
-      if (s1len == 0)
+      s1[s1len++] = '\0';
+      s2[s2len++] = '\0';
+
+      while (! (errno = 0, (diff = strcoll (s1, s2)) || errno))
 	{
-	  if (s2len != 0)
-	    diff = -1;
-	  break;
+	  /* strcoll found no difference, but perhaps it was fooled by NUL
+	     characters in the data.  Work around this problem by advancing
+	     past the NUL chars.  */
+	  size_t size1 = strlen (s1) + 1;
+	  size_t size2 = strlen (s2) + 1;
+	  s1 += size1;
+	  s2 += size2;
+	  s1len -= size1;
+	  s2len -= size2;
+
+	  if (s1len == 0)
+	    {
+	      if (s2len != 0)
+		diff = -1;
+	      break;
+	    }
+	  else if (s2len == 0)
+	    {
+	      diff = 1;
+	      break;
+	    }
 	}
-      else if (s2len == 0)
-	{
-	  diff = 1;
-	  break;
-	}
+
+      s1[s1len - 1] = n1;
+      s2[s2len - 1] = n2;
     }
 
-  s1[s1len - 1] = n1;
-  s2[s2len - 1] = n2;
-
 #else
 
   diff = memcmp (s1, s2, s1len < s2len ? s1len : s2len);