[PATCH 1/2] string: Speed up strcmp test data initialization
Magnus Lindholm <[email protected]> Wed, 5 Aug 2026 23:14:58 +0200
| Newsgroups | gmane.comp.lib.glibc.alpha |
|---|---|
| Message-ID | <[email protected]> |
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]> --- 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; -- 2.53.0