[PATCH] lib/string.c: Improve strcasecmp speed by not lowering if chars match.

From: Nathan Moinvaziri
Date: Mon Oct 24 2022 - 19:37:59 EST


With strings where many characters match exactly each character is needless=
ly
converted to lowercase before comparing. This patch improves the comparison
by only converting to lowercase after checking that the characters don't ma=
tch.

The more characters that match exactly the better performance we expect ver=
sus
the old function.

When running tests using Quick Benchmark with two matching 256 character
strings these changes result in anywhere between ~6-9x speed improvement.

* We use unsigned char instead of int similar to strncasecmp.
* We only subtract c1 - c2 when they are not equal.

Reviewed-by: Sergey Markelov <sergio_nsk@xxxxxxxx>
Reviewed-by: Steve Tucker <steven.r.tucker@xxxxxxxxx>
---
lib/string.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/lib/string.c b/lib/string.c
index 3371d26a0e39..51ad56db1b5d 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -64,13 +64,20 @@ EXPORT_SYMBOL(strncasecmp);
#ifndef __HAVE_ARCH_STRCASECMP
int strcasecmp(const char *s1, const char *s2)
{
- int c1, c2;
+ /* Yes, Virginia, it had better be unsigned */
+ unsigned char c1, c2;
=20
do {
- c1 =3D tolower(*s1++);
- c2 =3D tolower(*s2++);
- } while (c1 =3D=3D c2 && c1 !=3D 0);
- return c1 - c2;
+ c1 =3D *s1++;
+ c2 =3D *s2++;
+ if (c1 !=3D c2) {
+ c1 =3D tolower(c1);
+ c2 =3D tolower(c2);
+ if (c1 !=3D c2)
+ return (int)c1 - (int)c2;
+ }
+ } while (c1 !=3D 0);
+ return 0;
}
EXPORT_SYMBOL(strcasecmp);
#endif
--=20
2.37.2.windows.2