string_contains(): speed up by avoiding function calls where

possible.  This always called PyUnicode_Check() and PyString_Check(),
at least one of which would call PyType_IsSubtype().  Also, this would
call PyString_Size() on known string objects.
This commit is contained in:
Guido van Rossum 2002-08-24 06:57:49 +00:00
parent 9d6897accc
commit bf935fde15

View file

@ -991,24 +991,27 @@ string_contains(PyObject *a, PyObject *el)
{ {
const char *lhs, *rhs, *end; const char *lhs, *rhs, *end;
int size; int size;
if (!PyString_CheckExact(el)) {
#ifdef Py_USING_UNICODE #ifdef Py_USING_UNICODE
if (PyUnicode_Check(el)) if (PyUnicode_Check(el))
return PyUnicode_Contains(a, el); return PyUnicode_Contains(a, el);
#endif #endif
if (!PyString_Check(el)) { if (!PyString_Check(el)) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"'in <string>' requires string as left operand"); "'in <string>' requires string as left operand");
return -1; return -1;
}
} }
size = PyString_Size(el); size = PyString_GET_SIZE(el);
rhs = PyString_AS_STRING(el); rhs = PyString_AS_STRING(el);
lhs = PyString_AS_STRING(a); lhs = PyString_AS_STRING(a);
/* optimize for a single character */ /* optimize for a single character */
if (size == 1) if (size == 1)
return memchr(lhs, *rhs, PyString_Size(a)) != NULL; return memchr(lhs, *rhs, PyString_GET_SIZE(a)) != NULL;
end = lhs + (PyString_Size(a) - size); end = lhs + (PyString_GET_SIZE(a) - size);
while (lhs <= end) { while (lhs <= end) {
if (memcmp(lhs++, rhs, size) == 0) if (memcmp(lhs++, rhs, size) == 0)
return 1; return 1;