]> granicus.if.org Git - python/commitdiff
Issue #3106: Speedup some comparisons. This also removes the last call
authorAntoine Pitrou <solipsis@pitrou.net>
Sat, 20 Dec 2008 13:14:23 +0000 (13:14 +0000)
committerAntoine Pitrou <solipsis@pitrou.net>
Sat, 20 Dec 2008 13:14:23 +0000 (13:14 +0000)
to Py_CmpToRich from the codebase (in longobject.c).

Misc/NEWS
Objects/longobject.c
Objects/unicodeobject.c

index 9274a834a9da84ee795d65d62f876984afe18f17..98dae61c604fe0009ee1395d5ab2f2cd7643e734 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,8 @@ What's New in Python 3.1 alpha 0
 Core and Builtins
 -----------------
 
+- Issue #3106: Speedup some comparisons (str/str and int/int).
+
 - Issue #2183: Simplify and optimize bytecode for list, dict and set
   comprehensions. Original patch for list comprehensions by Neal Norwitz.
 
index 677221a61d2186ad36515012627b200e451ca07b..362d0ad23993d2d510ed0248fddbb22055910710 100644 (file)
@@ -2232,14 +2232,45 @@ long_compare(PyLongObject *a, PyLongObject *b)
        return sign < 0 ? -1 : sign > 0 ? 1 : 0;
 }
 
+#define TEST_COND(cond) \
+       ((cond) ? Py_True : Py_False)
+
 static PyObject *
 long_richcompare(PyObject *self, PyObject *other, int op)
 {
-       PyObject *result;
+       int result;
+       PyObject *v;
        CHECK_BINOP(self, other);
-       result = Py_CmpToRich(op, long_compare((PyLongObject*)self, 
-                                              (PyLongObject*)other));
-       return result;
+       if (self == other)
+               result = 0;
+       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
index 6f64a0791dbe71fe44601fd0acdf97e75c3d9ec4..38c3385ae829abb7a3f189774b064bce535a78eb 100644 (file)
@@ -6508,81 +6508,65 @@ PyUnicode_CompareWithASCIIString(PyObject* uni, const char* str)
     return 0;
 }
 
+
+#define TEST_COND(cond) \
+       ((cond) ? Py_True : Py_False)
+
 PyObject *PyUnicode_RichCompare(PyObject *left,
                                 PyObject *right,
                                 int op)
 {
     int result;
-
-    result = PyUnicode_Compare(left, right);
-    if (result == -1 && PyErr_Occurred())
-        goto onError;
-
-    /* Convert the return value to a Boolean */
-    switch (op) {
-    case Py_EQ:
-        result = (result == 0);
-        break;
-    case Py_NE:
-        result = (result != 0);
-        break;
-    case Py_LE:
-        result = (result <= 0);
-        break;
-    case Py_GE:
-        result = (result >= 0);
-        break;
-    case Py_LT:
-        result = (result == -1);
-        break;
-    case Py_GT:
-        result = (result == 1);
-        break;
-    }
-    return PyBool_FromLong(result);
-
- onError:
-
-    /* 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 (PyUnicode_Check(left) && PyUnicode_Check(right)) {
+        PyObject *v;
+        if (((PyUnicodeObject *) left)->length !=
+            ((PyUnicodeObject *) right)->length) {
+            if (op == Py_EQ) {
+                Py_INCREF(Py_False);
+                return Py_False;
+            }
+            if (op == Py_NE) {
+                Py_INCREF(Py_True);
+                return Py_True;
+            }
+        }
+        if (left == right)
+            result = 0;
+        else
+            result = unicode_compare((PyUnicodeObject *)left,
+                                     (PyUnicodeObject *)right);
+    
+        /* 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;
     }
-    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);
+    
+    Py_INCREF(Py_NotImplemented);
+    return Py_NotImplemented;
 }
 
 int PyUnicode_Contains(PyObject *container,