]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Merged revisions 67871 via svnmerge from
authorAntoine Pitrou <solipsis@pitrou.net>
Sat, 20 Dec 2008 13:23:02 +0000 (13:23 +0000)
committerAntoine Pitrou <solipsis@pitrou.net>
Sat, 20 Dec 2008 13:23:02 +0000 (13:23 +0000)
svn+ssh://pythondev@svn.python.org/python/branches/py3k

........
  r67871 | antoine.pitrou | 2008-12-20 14:14:23 +0100 (sam., 20 déc. 2008) | 4 lines

  Issue #3106: Speedup some comparisons. This also removes the last call
  to Py_CmpToRich from the codebase (in longobject.c).
........

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

index fa0d286c9ab5283a5a4f2574e0edf365c30b5ada..393b3fc89f80574c3d1567f650dd0353edcd58a2 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,8 @@ What's New in Python 3.0.1?
 Core and Builtins
 -----------------
 
+- Issue #3106: Speedup some comparisons (str/str and int/int).
+
 - Issue #2173: When getting device encoding, check that return value of
   nl_langinfo is not the empty string.  This was causing silent build
   failures on OS X.
index c28fe0a3f90756f3e9f80a809932d22b9761c932..cf71ca79cb549f480dac8bab446f79e6272fa6ed 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,