gh-120397: Optimize str.count() for single characters (#120398)

This commit is contained in:
Ruben Vorderman 2024-06-13 16:28:59 +02:00 committed by GitHub
parent 6ae254aaa0
commit 2078eb45ca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 21 additions and 0 deletions

View File

@ -0,0 +1,2 @@
Improve the througput by up to two times for the :meth:`str.count`, :meth:`bytes.count` and :meth:`bytearray.count`
methods for counting single characters.

View File

@ -753,6 +753,22 @@ STRINGLIB(count_char)(const STRINGLIB_CHAR *s, Py_ssize_t n,
} }
static inline Py_ssize_t
STRINGLIB(count_char_no_maxcount)(const STRINGLIB_CHAR *s, Py_ssize_t n,
const STRINGLIB_CHAR p0)
/* A specialized function of count_char that does not cut off at a maximum.
As a result, the compiler is able to vectorize the loop. */
{
Py_ssize_t count = 0;
for (Py_ssize_t i = 0; i < n; i++) {
if (s[i] == p0) {
count++;
}
}
return count;
}
Py_LOCAL_INLINE(Py_ssize_t) Py_LOCAL_INLINE(Py_ssize_t)
FASTSEARCH(const STRINGLIB_CHAR* s, Py_ssize_t n, FASTSEARCH(const STRINGLIB_CHAR* s, Py_ssize_t n,
const STRINGLIB_CHAR* p, Py_ssize_t m, const STRINGLIB_CHAR* p, Py_ssize_t m,
@ -773,6 +789,9 @@ FASTSEARCH(const STRINGLIB_CHAR* s, Py_ssize_t n,
else if (mode == FAST_RSEARCH) else if (mode == FAST_RSEARCH)
return STRINGLIB(rfind_char)(s, n, p[0]); return STRINGLIB(rfind_char)(s, n, p[0]);
else { else {
if (maxcount == PY_SSIZE_T_MAX) {
return STRINGLIB(count_char_no_maxcount)(s, n, p[0]);
}
return STRINGLIB(count_char)(s, n, p[0], maxcount); return STRINGLIB(count_char)(s, n, p[0], maxcount);
} }
} }