summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2006-08-14 16:20:49 +0000
committerPaul Eggert <eggert@cs.ucla.edu>2006-08-14 16:20:49 +0000
commit1a00d99c2f1f4006ccad3b2289839676d0b282de (patch)
treecca69202cfa1de6b6c842f86c27c8d9f0b9bcdd8 /lib
parent418a7c8c43a610e5cf261c75168692887ba43c98 (diff)
downloadcoreutils-1a00d99c2f1f4006ccad3b2289839676d0b282de.tar.xz
(memcoll): Optimize for the common case where the
arguments are bytewise equal.
Diffstat (limited to 'lib')
-rw-r--r--lib/ChangeLog5
-rw-r--r--lib/memcoll.c65
2 files changed, 42 insertions, 28 deletions
diff --git a/lib/ChangeLog b/lib/ChangeLog
index 9fa61ac7b..2d2203ea8 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,8 @@
+2006-08-14 Paul Eggert <eggert@cs.ucla.edu>
+
+ * memcoll.c (memcoll): Optimize for the common case where the
+ arguments are bytewise equal.
+
2006-08-11 Paul Eggert <eggert@cs.ucla.edu>
* pipe-safer.c (pipe_safer): Fix misspelling: HAVE_FUNC_PIPE ->
diff --git a/lib/memcoll.c b/lib/memcoll.c
index 82d889f40..7f61a6b58 100644
--- a/lib/memcoll.c
+++ b/lib/memcoll.c
@@ -38,39 +38,48 @@ memcoll (char *s1, size_t s1len, char *s2, size_t s2len)
#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;
-
- if (s1len == 0)
- {
- if (s2len != 0)
- diff = -1;
- break;
- }
- else if (s2len == 0)
+ char n1 = s1[s1len];
+ char n2 = s2[s2len];
+
+ s1[s1len++] = '\0';
+ s2[s2len++] = '\0';
+
+ while (! (errno = 0, (diff = strcoll (s1, s2)) || errno))
{
- 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;
+ }
}
- }
- s1[s1len - 1] = n1;
- s2[s2len - 1] = n2;
+ s1[s1len - 1] = n1;
+ s2[s2len - 1] = n2;
+ }
#else