Re: [PATCH 1/2] string: Speed up strcmp test data initialization

Adhemerval Zanella Netto <[email protected]> Fri, 7 Aug 2026 10:35:48 -0300
Newsgroups gmane.comp.lib.glibc.alpha
Organization Linaro
Message-ID <[email protected]>

On 05/08/26 18:14, Magnus Lindholm wrote:
> The strcmp and strncmp tests repeatedly initialize large buffers for
> many combinations of lengths and alignments.  The existing loops
> perform a remainder operation and two individual stores for every
> element.
> 
> Generate at most max_char elements using an additive recurrence.  The
> recurrence produces the same sequence as the existing multiplication
> and remainder expression.  Expand this initial pattern using bulk
> copies, and then copy the completed first buffer to the second buffer.
> 
> This preserves the generated test data while substantially reducing
> the initialization cost on slower systems.
> 
> The change also applies to the wcscmp and wcsncmp tests, which include
> the same test sources.
> 
> Signed-off-by: Magnus Lindholm <[email protected]>

Nice catch, LTGM.

Reviewed-by: Adhemerval Zanella  <[email protected]>

> ---
>  string/test-strcmp.c  | 28 ++++++++++++++++++++++++++--
>  string/test-strncmp.c | 28 ++++++++++++++++++++++++++--
>  2 files changed, 52 insertions(+), 4 deletions(-)
> 
> diff --git a/string/test-strcmp.c b/string/test-strcmp.c
> index 76ccff46e2..ca52827b11 100644
> --- a/string/test-strcmp.c
> +++ b/string/test-strcmp.c
> @@ -156,6 +156,10 @@ 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 pattern_len;
> +  size_t step
> +    = (23U << ((CHARBYTES - 1) * 8)) % (size_t) max_char;
>  
>    CHAR *s1, *s2;
>  
> @@ -179,8 +183,28 @@ do_test (size_t align1, size_t align2, size_t len, int max_char,
>    i = align2 + CHARBYTES * (len + 2);
>    s2 = (CHAR *)(buf2 + ((page_size - i) / 16 * 16) + align2);
>  
> -  for (i = 0; i < len; i++)
> -    s1[i] = s2[i] = 1 + (23 << ((CHARBYTES - 1) * 8)) * i % max_char;
> +  /* The generated sequence repeats after at most max_char elements.  */
> +  pattern_len
> +    = len < (size_t) max_char ? len : (size_t) max_char;
> +
> +  for (i = 0; i < pattern_len; i++)
> +    {
> +      s1[i] = 1 + value;
> +
> +      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);
> +      i += copy;
> +    }
> +
> +  MEMCPY (s2, s1, len);
>  
>    s1[len] = s2[len] = 0;
>    s1[len + 1] = 23;
> diff --git a/string/test-strncmp.c b/string/test-strncmp.c
> index 54ada39eb2..9da0f21f60 100644
> --- a/string/test-strncmp.c
> +++ b/string/test-strncmp.c
> @@ -190,6 +190,9 @@ do_test_n (size_t align1, size_t align2, size_t len, size_t n, int n_in_bounds,
>  {
>    size_t i, buf_bound;
>    CHAR *s1, *s2, *s1_end, *s2_end;
> +  size_t value = 0;
> +  size_t pattern_len;
> +  size_t step = (23U << ((CHARBYTES - 1) * 8)) % (size_t) max_char;
>  
>    align1 &= ~(CHARBYTES - 1);
>    align2 &= ~(CHARBYTES - 1);
> @@ -216,8 +219,29 @@ do_test_n (size_t align1, size_t align2, size_t len, size_t n, int n_in_bounds,
>        s2[n] = 23;
>      }
>  
> -  for (i = 0; i < buf_bound; i++)
> -    s1[i] = s2[i] = 1 + (23 << ((CHARBYTES - 1) * 8)) * i % max_char;
> +  /* The generated sequence repeats after at most max_char elements.  */
> +  pattern_len
> +    = buf_bound < (size_t) max_char
> +      ? buf_bound : (size_t) max_char;
> +
> +  for (i = 0; i < pattern_len; i++)
> +    {
> +      s1[i] = 1 + value;
> +
> +      value += step;
> +      if (value >= (size_t) max_char)
> +        value -= max_char;
> +    }
> +
> +  while (i < buf_bound)
> +    {
> +      size_t copy = i < buf_bound - i ? i : buf_bound - i;
> +
> +      MEMCPY (s1 + i, s1, copy);
> +      i += copy;
> +    }
> +
> +  MEMCPY (s2, s1, buf_bound);
>  
>    s1[len] = 0;
>    s2[len] = 0;