mirror of
https://github.com/python/cpython.git
synced 2025-09-18 14:40:43 +00:00
Issue #3106: Speedup some comparisons. This also removes the last call
to Py_CmpToRich from the codebase (in longobject.c).
This commit is contained in:
parent
c9928ccf01
commit
51f3ef9da0
3 changed files with 90 additions and 73 deletions
|
@ -12,6 +12,8 @@ What's New in Python 3.1 alpha 0
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #3106: Speedup some comparisons (str/str and int/int).
|
||||||
|
|
||||||
- Issue #2183: Simplify and optimize bytecode for list, dict and set
|
- Issue #2183: Simplify and optimize bytecode for list, dict and set
|
||||||
comprehensions. Original patch for list comprehensions by Neal Norwitz.
|
comprehensions. Original patch for list comprehensions by Neal Norwitz.
|
||||||
|
|
||||||
|
|
|
@ -2232,14 +2232,45 @@ long_compare(PyLongObject *a, PyLongObject *b)
|
||||||
return sign < 0 ? -1 : sign > 0 ? 1 : 0;
|
return sign < 0 ? -1 : sign > 0 ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define TEST_COND(cond) \
|
||||||
|
((cond) ? Py_True : Py_False)
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
long_richcompare(PyObject *self, PyObject *other, int op)
|
long_richcompare(PyObject *self, PyObject *other, int op)
|
||||||
{
|
{
|
||||||
PyObject *result;
|
int result;
|
||||||
|
PyObject *v;
|
||||||
CHECK_BINOP(self, other);
|
CHECK_BINOP(self, other);
|
||||||
result = Py_CmpToRich(op, long_compare((PyLongObject*)self,
|
if (self == other)
|
||||||
(PyLongObject*)other));
|
result = 0;
|
||||||
return result;
|
else
|
||||||
|
result = long_compare((PyLongObject*)self, (PyLongObject*)other);
|
||||||
|
/* Convert the return value to a Boolean */
|
||||||
|
switch (op) {
|
||||||
|
case Py_EQ:
|
||||||
|
v = TEST_COND(result == 0);
|
||||||
|
break;
|
||||||
|
case Py_NE:
|
||||||
|
v = TEST_COND(result != 0);
|
||||||
|
break;
|
||||||
|
case Py_LE:
|
||||||
|
v = TEST_COND(result <= 0);
|
||||||
|
break;
|
||||||
|
case Py_GE:
|
||||||
|
v = TEST_COND(result >= 0);
|
||||||
|
break;
|
||||||
|
case Py_LT:
|
||||||
|
v = TEST_COND(result == -1);
|
||||||
|
break;
|
||||||
|
case Py_GT:
|
||||||
|
v = TEST_COND(result == 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PyErr_BadArgument();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Py_INCREF(v);
|
||||||
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long
|
static long
|
||||||
|
|
|
@ -6508,81 +6508,65 @@ PyUnicode_CompareWithASCIIString(PyObject* uni, const char* str)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define TEST_COND(cond) \
|
||||||
|
((cond) ? Py_True : Py_False)
|
||||||
|
|
||||||
PyObject *PyUnicode_RichCompare(PyObject *left,
|
PyObject *PyUnicode_RichCompare(PyObject *left,
|
||||||
PyObject *right,
|
PyObject *right,
|
||||||
int op)
|
int op)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
result = PyUnicode_Compare(left, right);
|
if (PyUnicode_Check(left) && PyUnicode_Check(right)) {
|
||||||
if (result == -1 && PyErr_Occurred())
|
PyObject *v;
|
||||||
goto onError;
|
if (((PyUnicodeObject *) left)->length !=
|
||||||
|
((PyUnicodeObject *) right)->length) {
|
||||||
/* Convert the return value to a Boolean */
|
if (op == Py_EQ) {
|
||||||
switch (op) {
|
Py_INCREF(Py_False);
|
||||||
case Py_EQ:
|
return Py_False;
|
||||||
result = (result == 0);
|
}
|
||||||
break;
|
if (op == Py_NE) {
|
||||||
case Py_NE:
|
Py_INCREF(Py_True);
|
||||||
result = (result != 0);
|
return Py_True;
|
||||||
break;
|
}
|
||||||
case Py_LE:
|
}
|
||||||
result = (result <= 0);
|
if (left == right)
|
||||||
break;
|
result = 0;
|
||||||
case Py_GE:
|
else
|
||||||
result = (result >= 0);
|
result = unicode_compare((PyUnicodeObject *)left,
|
||||||
break;
|
(PyUnicodeObject *)right);
|
||||||
case Py_LT:
|
|
||||||
result = (result == -1);
|
/* Convert the return value to a Boolean */
|
||||||
break;
|
switch (op) {
|
||||||
case Py_GT:
|
case Py_EQ:
|
||||||
result = (result == 1);
|
v = TEST_COND(result == 0);
|
||||||
break;
|
break;
|
||||||
|
case Py_NE:
|
||||||
|
v = TEST_COND(result != 0);
|
||||||
|
break;
|
||||||
|
case Py_LE:
|
||||||
|
v = TEST_COND(result <= 0);
|
||||||
|
break;
|
||||||
|
case Py_GE:
|
||||||
|
v = TEST_COND(result >= 0);
|
||||||
|
break;
|
||||||
|
case Py_LT:
|
||||||
|
v = TEST_COND(result == -1);
|
||||||
|
break;
|
||||||
|
case Py_GT:
|
||||||
|
v = TEST_COND(result == 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PyErr_BadArgument();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Py_INCREF(v);
|
||||||
|
return v;
|
||||||
}
|
}
|
||||||
return PyBool_FromLong(result);
|
|
||||||
|
Py_INCREF(Py_NotImplemented);
|
||||||
onError:
|
return Py_NotImplemented;
|
||||||
|
|
||||||
/* Standard case
|
|
||||||
|
|
||||||
Type errors mean that PyUnicode_FromObject() could not convert
|
|
||||||
one of the arguments (usually the right hand side) to Unicode,
|
|
||||||
ie. we can't handle the comparison request. However, it is
|
|
||||||
possible that the other object knows a comparison method, which
|
|
||||||
is why we return Py_NotImplemented to give the other object a
|
|
||||||
chance.
|
|
||||||
|
|
||||||
*/
|
|
||||||
if (PyErr_ExceptionMatches(PyExc_TypeError)) {
|
|
||||||
PyErr_Clear();
|
|
||||||
Py_INCREF(Py_NotImplemented);
|
|
||||||
return Py_NotImplemented;
|
|
||||||
}
|
|
||||||
if (op != Py_EQ && op != Py_NE)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* Equality comparison.
|
|
||||||
|
|
||||||
This is a special case: we silence any PyExc_UnicodeDecodeError
|
|
||||||
and instead turn it into a PyErr_UnicodeWarning.
|
|
||||||
|
|
||||||
*/
|
|
||||||
if (!PyErr_ExceptionMatches(PyExc_UnicodeDecodeError))
|
|
||||||
return NULL;
|
|
||||||
PyErr_Clear();
|
|
||||||
if (PyErr_WarnEx(PyExc_UnicodeWarning,
|
|
||||||
(op == Py_EQ) ?
|
|
||||||
"equal comparison "
|
|
||||||
"failed to convert both arguments to str - "
|
|
||||||
"interpreting them as being unequal"
|
|
||||||
:
|
|
||||||
"Unicode unequal comparison "
|
|
||||||
"failed to convert both arguments to str - "
|
|
||||||
"interpreting them as being unequal",
|
|
||||||
1) < 0)
|
|
||||||
return NULL;
|
|
||||||
result = (op == Py_NE);
|
|
||||||
return PyBool_FromLong(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PyUnicode_Contains(PyObject *container,
|
int PyUnicode_Contains(PyObject *container,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue