diff -r 388e43bb519d Objects/bytesobject.c --- a/Objects/bytesobject.c Thu Oct 18 21:31:22 2012 +0200 +++ b/Objects/bytesobject.c Fri Oct 19 14:24:57 2012 +0200 @@ -797,6 +797,33 @@ bytes_item(PyBytesObject *a, register Py return PyLong_FromLong((unsigned char)a->ob_sval[i]); } +static int +bytes_compare_eq(PyBytesObject *a, PyBytesObject *b) +{ + Py_ssize_t len; + char *data1, *data2; + + len = Py_SIZE(a); + if (Py_SIZE(b) != len) + return 0; + + /* if the hash values are different, the operands are different */ + if (a->ob_shash != -1 + && b->ob_shash != -1 + && a->ob_shash != b->ob_shash) + return 0; + + data1 = a->ob_sval; + data2 = b->ob_sval; + /* Compare first and last bytes to avoid the cost of a function call + if they are different */ + if (data1[0] != data2[0]) + return 0; + if (data1[len-1] != data2[len-1]) + return 0; + return (memcmp(data1 + 1, data2 + 1, len - 2) == 0); +} + static PyObject* bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op) { @@ -819,6 +846,7 @@ bytes_richcompare(PyBytesObject *a, PyBy result = Py_NotImplemented; goto out; } + if (a == b) { switch (op) { case Py_EQ:case Py_LE:case Py_GE: @@ -829,16 +857,11 @@ bytes_richcompare(PyBytesObject *a, PyBy goto out; } } - if (op == Py_EQ) { - /* Supporting Py_NE here as well does not save - much time, since Py_NE is rarely used. */ - if (Py_SIZE(a) == Py_SIZE(b) - && (a->ob_sval[0] == b->ob_sval[0] - && memcmp(a->ob_sval, b->ob_sval, Py_SIZE(a)) == 0)) { - result = Py_True; - } else { - result = Py_False; - } + if (op == Py_EQ || op == Py_NE) { + c = bytes_compare_eq(a, b); + if (op == Py_NE) + c = !c; + result = c?Py_True:Py_False; goto out; } len_a = Py_SIZE(a); len_b = Py_SIZE(b); diff -r 388e43bb519d Objects/unicodeobject.c --- a/Objects/unicodeobject.c Thu Oct 18 21:31:22 2012 +0200 +++ b/Objects/unicodeobject.c Fri Oct 19 14:24:57 2012 +0200 @@ -10296,6 +10296,34 @@ unicode_compare(PyObject *str1, PyObject return 1; } +static int +unicode_compare_eq(PyObject *str1, PyObject *str2) +{ + int kind; + Py_ssize_t len; + int cmp; + + /* a string is equal to itself */ + if (str1 == str2) + return 1; + + /* if the hash values are different, the operands are different */ + if (_PyUnicode_HASH(str1) != -1 + && _PyUnicode_HASH(str2) != -1 + && _PyUnicode_HASH(str1) != _PyUnicode_HASH(str2)) + return 0; + + kind = PyUnicode_KIND(str1); + if (PyUnicode_KIND(str2) != kind) + return 0; + len = PyUnicode_GET_LENGTH(str1); + if (PyUnicode_GET_LENGTH(str2) != len) + return 0; + + cmp = memcmp(PyUnicode_DATA(str1), PyUnicode_DATA(str2), len * kind); + return (cmp == 0); +} + int PyUnicode_Compare(PyObject *left, PyObject *right) { @@ -10346,23 +10374,23 @@ PyObject * PyUnicode_RichCompare(PyObject *left, PyObject *right, int op) { int result; - - if (PyUnicode_Check(left) && PyUnicode_Check(right)) { - PyObject *v; - if (PyUnicode_READY(left) == -1 || - PyUnicode_READY(right) == -1) - return NULL; - if (PyUnicode_GET_LENGTH(left) != PyUnicode_GET_LENGTH(right) || - PyUnicode_KIND(left) != PyUnicode_KIND(right)) { - if (op == Py_EQ) { - Py_INCREF(Py_False); - return Py_False; - } - if (op == Py_NE) { - Py_INCREF(Py_True); - return Py_True; - } - } + PyObject *v; + + if (!PyUnicode_Check(left) || !PyUnicode_Check(right)) + Py_RETURN_NOTIMPLEMENTED; + + if (PyUnicode_READY(left) == -1 || + PyUnicode_READY(right) == -1) + return NULL; + + if (op == Py_EQ || op == Py_NE) { + result = unicode_compare_eq(left, right); + if (op == Py_EQ) + v = TEST_COND(result == 1); + else + v = TEST_COND(result == 0); + } + else { result = unicode_compare(left, right); /* Convert the return value to a Boolean */ @@ -10389,11 +10417,9 @@ PyUnicode_RichCompare(PyObject *left, Py PyErr_BadArgument(); return NULL; } - Py_INCREF(v); - return v; - } - - Py_RETURN_NOTIMPLEMENTED; + } + Py_INCREF(v); + return v; } int