* Beef-up tests for str.count().

* Speed-up str.count() by using memchr() to fly between first char matches.
This commit is contained in:
Raymond Hettinger 2005-02-20 09:54:53 +00:00
parent 7cbf1bcb3e
commit 57e7447c44
2 changed files with 35 additions and 2 deletions

View File

@ -114,6 +114,33 @@ class CommonTest(unittest.TestCase):
self.checkraises(TypeError, 'hello', 'count')
self.checkraises(TypeError, 'hello', 'count', 42)
# For a variety of combinations,
# verify that str.count() matches an equivalent function
# replacing all occurrences and then differencing the string lengths
charset = ['', 'a', 'b']
digits = 7
base = len(charset)
teststrings = set()
for i in xrange(base ** digits):
entry = []
for j in xrange(digits):
i, m = divmod(i, base)
entry.append(charset[m])
teststrings.add(''.join(entry))
teststrings = list(teststrings)
for i in teststrings:
i = self.fixtype(i)
n = len(i)
for j in teststrings:
r1 = i.count(j)
if j:
r2, rem = divmod(n - len(i.replace(j, '')), len(j))
else:
r2, rem = len(i)+1, 0
if rem or r1 != r2:
self.assertEqual(rem, 0)
self.assertEqual(r1, r2)
def test_find(self):
self.checkequal(0, 'abcdefghiabc', 'find', 'abc')
self.checkequal(9, 'abcdefghiabc', 'find', 'abc', 1)
@ -135,6 +162,7 @@ class CommonTest(unittest.TestCase):
i, m = divmod(i, base)
entry.append(charset[m])
teststrings.add(''.join(entry))
teststrings = list(teststrings)
for i in teststrings:
i = self.fixtype(i)
for j in teststrings:

View File

@ -2145,7 +2145,7 @@ interpreted as in slice notation.");
static PyObject *
string_count(PyStringObject *self, PyObject *args)
{
const char *s = PyString_AS_STRING(self), *sub;
const char *s = PyString_AS_STRING(self), *sub, *t;
int len = PyString_GET_SIZE(self), n;
int i = 0, last = INT_MAX;
int m, r;
@ -2186,11 +2186,16 @@ string_count(PyStringObject *self, PyObject *args)
} else {
i++;
}
if (i >= m)
break;
t = memchr(s+i, sub[0], m-i);
if (t == NULL)
break;
i = t - s;
}
return PyInt_FromLong((long) r);
}
PyDoc_STRVAR(swapcase__doc__,
"S.swapcase() -> string\n\
\n\