Issue #16286: optimize PyUnicode_RichCompare() for identical strings (same

pointer) for any operator, not only Py_EQ and Py_NE.

Code of bytes_richcompare() and PyUnicode_RichCompare() is now closer.
This commit is contained in:
Victor Stinner 2013-11-04 11:23:05 +01:00
parent c8bc5377ac
commit fd9e44db37
2 changed files with 35 additions and 12 deletions

View File

@ -842,12 +842,20 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op)
} }
else if (a == b) { else if (a == b) {
switch (op) { switch (op) {
case Py_EQ:case Py_LE:case Py_GE: case Py_EQ:
case Py_LE:
case Py_GE:
/* a string is equal to itself */
result = Py_True; result = Py_True;
break; break;
case Py_NE:case Py_LT:case Py_GT: case Py_NE:
case Py_LT:
case Py_GT:
result = Py_False; result = Py_False;
break; break;
default:
PyErr_BadArgument();
return NULL;
} }
} }
else if (op == Py_EQ || op == Py_NE) { else if (op == Py_EQ || op == Py_NE) {
@ -856,11 +864,12 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op)
result = eq ? Py_True : Py_False; result = eq ? Py_True : Py_False;
} }
else { else {
len_a = Py_SIZE(a); len_b = Py_SIZE(b); len_a = Py_SIZE(a);
min_len = (len_a < len_b) ? len_a : len_b; len_b = Py_SIZE(b);
min_len = Py_MIN(len_a, len_b);
if (min_len > 0) { if (min_len > 0) {
c = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval); c = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval);
if (c==0) if (c == 0)
c = memcmp(a->ob_sval, b->ob_sval, min_len); c = memcmp(a->ob_sval, b->ob_sval, min_len);
} }
else else
@ -873,8 +882,8 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op)
case Py_GT: c = c > 0; break; case Py_GT: c = c > 0; break;
case Py_GE: c = c >= 0; break; case Py_GE: c = c >= 0; break;
default: default:
assert(op != Py_EQ && op != Py_NE); PyErr_BadArgument();
Py_RETURN_NOTIMPLEMENTED; return NULL;
} }
result = c ? Py_True : Py_False; result = c ? Py_True : Py_False;
} }

View File

@ -10534,10 +10534,6 @@ unicode_compare_eq(PyObject *str1, PyObject *str2)
Py_ssize_t len; Py_ssize_t len;
int cmp; int cmp;
/* a string is equal to itself */
if (str1 == str2)
return 1;
len = PyUnicode_GET_LENGTH(str1); len = PyUnicode_GET_LENGTH(str1);
if (PyUnicode_GET_LENGTH(str2) != len) if (PyUnicode_GET_LENGTH(str2) != len)
return 0; return 0;
@ -10628,7 +10624,25 @@ PyUnicode_RichCompare(PyObject *left, PyObject *right, int op)
PyUnicode_READY(right) == -1) PyUnicode_READY(right) == -1)
return NULL; return NULL;
if (op == Py_EQ || op == Py_NE) { if (left == right) {
switch (op) {
case Py_EQ:
case Py_LE:
case Py_GE:
/* a string is equal to itself */
v = Py_True;
break;
case Py_NE:
case Py_LT:
case Py_GT:
v = Py_False;
break;
default:
PyErr_BadArgument();
return NULL;
}
}
else if (op == Py_EQ || op == Py_NE) {
result = unicode_compare_eq(left, right); result = unicode_compare_eq(left, right);
result ^= (op == Py_NE); result ^= (op == Py_NE);
v = TEST_COND(result); v = TEST_COND(result);