Re: [PATCH 2/2] string: Speed up strcasecmp test data initialization
Adhemerval Zanella Netto <[email protected]> Fri, 7 Aug 2026 10:35:55 -0300
| Newsgroups | gmane.comp.lib.glibc.alpha |
|---|---|
| Organization | Linaro |
| Message-ID | <[email protected]> |
On 05/08/26 18:14, Magnus Lindholm wrote: > 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 <[email protected]> Nice catch, LTGM. Reviewed-by: Adhemerval Zanella <[email protected]> > --- > string/test-strcasecmp.c | 22 ++++++++++++++++++++-- > string/test-strncasecmp.c | 23 +++++++++++++++++++++-- > 2 files changed, 41 insertions(+), 4 deletions(-) > > diff --git a/string/test-strcasecmp.c b/string/test-strcasecmp.c > index a5235fa1bb..d090dcbf36 100644 > --- a/string/test-strcasecmp.c > +++ b/string/test-strcasecmp.c > @@ -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; > diff --git a/string/test-strncasecmp.c b/string/test-strncasecmp.c > index 035c680532..6b00113e66 100644 > --- a/string/test-strncasecmp.c > +++ b/string/test-strncasecmp.c > @@ -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;