diff -r 13a05ed33cf7 Objects/bytesobject.c --- a/Objects/bytesobject.c Fri Nov 01 00:55:30 2013 +0100 +++ b/Objects/bytesobject.c Fri Nov 01 02:57:01 2013 +0100 @@ -802,6 +802,29 @@ bytes_item(PyBytesObject *a, Py_ssize_t return PyLong_FromLong((unsigned char)a->ob_sval[i]); } +static int +bytes_compare_eq(PyBytesObject *a, PyBytesObject *b) +{ + int cmp; + Py_ssize_t len; + + /* if the hash values are different, the operands are different */ + if (a->ob_shash != b->ob_shash + && a->ob_shash != -1 + && b->ob_shash != -1) + return 0; + + len = Py_SIZE(a); + if (Py_SIZE(b) != len) + return 0; + + if (a->ob_sval[0] != b->ob_sval[0]) + return 0; + + cmp = memcmp(a->ob_sval, b->ob_sval, len); + return (cmp == 0); +} + static PyObject* bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op) { @@ -822,53 +845,46 @@ bytes_richcompare(PyBytesObject *a, PyBy return NULL; } result = Py_NotImplemented; - goto out; } - if (a == b) { + else if (a == b) { switch (op) { case Py_EQ:case Py_LE:case Py_GE: result = Py_True; - goto out; + break; case Py_NE:case Py_LT:case Py_GT: result = Py_False; - goto out; + break; } } - 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; + else if (op == Py_EQ || op == Py_NE) { + int eq = bytes_compare_eq(a, b); + eq ^= (op == Py_NE); + result = eq ? Py_True : Py_False; + } + else { + len_a = Py_SIZE(a); len_b = Py_SIZE(b); + min_len = (len_a < len_b) ? len_a : len_b; + if (min_len > 0) { + c = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval); + if (c==0) + c = memcmp(a->ob_sval, b->ob_sval, min_len); } - goto out; + else + c = 0; + if (c == 0) + c = (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0; + switch (op) { + case Py_LT: c = c < 0; break; + case Py_LE: c = c <= 0; break; + case Py_GT: c = c > 0; break; + case Py_GE: c = c >= 0; break; + default: + assert(op != Py_EQ && op != Py_NE); + Py_RETURN_NOTIMPLEMENTED; + } + result = c ? Py_True : Py_False; } - len_a = Py_SIZE(a); len_b = Py_SIZE(b); - min_len = (len_a < len_b) ? len_a : len_b; - if (min_len > 0) { - c = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval); - if (c==0) - c = memcmp(a->ob_sval, b->ob_sval, min_len); - } else - c = 0; - if (c == 0) - c = (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0; - switch (op) { - case Py_LT: c = c < 0; break; - case Py_LE: c = c <= 0; break; - case Py_EQ: assert(0); break; /* unreachable */ - case Py_NE: c = c != 0; break; - case Py_GT: c = c > 0; break; - case Py_GE: c = c >= 0; break; - default: - result = Py_NotImplemented; - goto out; - } - result = c ? Py_True : Py_False; - out: + Py_INCREF(result); return result; } diff -r 13a05ed33cf7 Objects/unicodeobject.c --- a/Objects/unicodeobject.c Fri Nov 01 00:55:30 2013 +0100 +++ b/Objects/unicodeobject.c Fri Nov 01 02:57:01 2013 +0100 @@ -10538,6 +10538,12 @@ unicode_compare_eq(PyObject *str1, PyObj if (str1 == str2) return 1; + /* if the hash values are different, the operands are different */ + if (_PyUnicode_HASH(str1) != _PyUnicode_HASH(str2) + && _PyUnicode_HASH(str1) != -1 + && _PyUnicode_HASH(str2) != -1) + return 0; + len = PyUnicode_GET_LENGTH(str1); if (PyUnicode_GET_LENGTH(str2) != len) return 0; @@ -10630,10 +10636,8 @@ PyUnicode_RichCompare(PyObject *left, Py if (op == Py_EQ || op == Py_NE) { result = unicode_compare_eq(left, right); - if (op == Py_EQ) - v = TEST_COND(result); - else - v = TEST_COND(!result); + result ^= (op == Py_NE); + v = TEST_COND(result); } else { result = unicode_compare(left, right);