[PATCH 1/2] string: Speed up strcmp test data initialization
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Fri Aug 7 13:35:48 GMT 2026
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 <linmag7@gmail.com>
Nice catch, LTGM.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> ---
> 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;
More information about the Libc-alpha
mailing list