* Beef-up tests for str.count().
* Speed-up str.count() by using memchr() to fly between first char matches.
This commit is contained in:
parent
7cbf1bcb3e
commit
57e7447c44
|
@ -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:
|
||||
|
|
|
@ -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\
|
||||
|
|
Loading…
Reference in New Issue