]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
string: Speed up strcasecmp test data initialization master
authorMagnus Lindholm <linmag7@gmail.com>
Wed, 5 Aug 2026 21:14:59 +0000 (23:14 +0200)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Fri, 7 Aug 2026 13:47:23 +0000 (10:47 -0300)
The strcasecmp and strncasecmp tests repeatedly initialize large
buffers for many combinations of lengths and alignments.  The existing
loops perform a remainder operation and call toupper and tolower for
every element.

Generate at most max_char elements using an additive recurrence and
apply the case conversions while creating this initial pattern.  The
recurrence produces the same sequence as the existing multiplication
and remainder expression.  Expand the completed pattern using bulk
copies.

This preserves the generated test data and locale-dependent case
conversion while substantially reducing the initialization cost on
slower systems.

Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
string/test-strcasecmp.c
string/test-strncasecmp.c

index a5235fa1bb7cf5e3fbd2665ef0ce0d5a04223439..d090dcbf3614d60a14cab1033881727f608a464c 100644 (file)
@@ -63,6 +63,9 @@ do_test (size_t align1, size_t align2, size_t len, int max_char,
         int exp_result)
 {
   size_t i;
+  size_t value = 0;
+  size_t step = 23U % (size_t) max_char;
+  size_t pattern_len;
   char *s1, *s2;
 
   if (len == 0)
@@ -80,10 +83,25 @@ do_test (size_t align1, size_t align2, size_t len, int max_char,
   s1 = (char *) (buf1 + align1);
   s2 = (char *) (buf2 + align2);
 
-  for (i = 0; i < len; i++)
+  pattern_len
+    = len < (size_t) max_char ? len : (size_t) max_char;
+
+  for (i = 0; i < pattern_len; i++)
     {
-      s1[i] = toupper (1 + 23 * i % max_char);
+      s1[i] = toupper (1 + value);
       s2[i] = tolower (s1[i]);
+      value += step;
+      if (value >= (size_t) max_char)
+        value -= max_char;
+    }
+
+  while (i < len)
+    {
+      size_t copy = i < len - i ? i : len - i;
+
+      memcpy (s1 + i, s1, copy);
+      memcpy (s2 + i, s2, copy);
+      i += copy;
     }
 
   s1[len] = s2[len] = 0;
index 035c68053257143c838a235f6a47f67fe04345cd..6b00113e661ed85505ccd708234648303dcfa813 100644 (file)
@@ -83,6 +83,9 @@ do_test (size_t align1, size_t align2, size_t n, size_t len, int max_char,
         int exp_result)
 {
   size_t i;
+  size_t value = 0;
+  size_t step = 23U % (size_t) max_char;
+  size_t pattern_len;
   char *s1, *s2;
 
   if (len == 0)
@@ -100,10 +103,26 @@ do_test (size_t align1, size_t align2, size_t n, size_t len, int max_char,
   s1 = (char *) (buf1 + align1);
   s2 = (char *) (buf2 + align2);
 
-  for (i = 0; i < len; i++)
+  pattern_len
+    = len < (size_t) max_char ? len : (size_t) max_char;
+
+  for (i = 0; i < pattern_len; i++)
     {
-      s1[i] = toupper (1 + 23 * i % max_char);
+      s1[i] = toupper (1 + value);
       s2[i] = tolower (s1[i]);
+
+      value += step;
+      if (value >= (size_t) max_char)
+        value -= max_char;
+    }
+
+  while (i < len)
+    {
+      size_t copy = i < len - i ? i : len - i;
+
+      memcpy (s1 + i, s1, copy);
+      memcpy (s2 + i, s2, copy);
+      i += copy;
     }
 
   s1[len] = s2[len] = 0;