[Python-checkins] r67873 - in python/branches/release30-maint: Misc/NEWS Objects/longobject.c Objects/unicodeobject.c

antoine.pitrou python-checkins at python.org
Sat Dec 20 14:23:02 CET 2008


Author: antoine.pitrou
Date: Sat Dec 20 14:23:02 2008
New Revision: 67873

Log:
Merged revisions 67871 via svnmerge from 
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).
........


Modified:
   python/branches/release30-maint/   (props changed)
   python/branches/release30-maint/Misc/NEWS
   python/branches/release30-maint/Objects/longobject.c
   python/branches/release30-maint/Objects/unicodeobject.c

Modified: python/branches/release30-maint/Misc/NEWS
==============================================================================
--- python/branches/release30-maint/Misc/NEWS	(original)
+++ python/branches/release30-maint/Misc/NEWS	Sat Dec 20 14:23:02 2008
@@ -12,6 +12,8 @@
 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.

Modified: python/branches/release30-maint/Objects/longobject.c
==============================================================================
--- python/branches/release30-maint/Objects/longobject.c	(original)
+++ python/branches/release30-maint/Objects/longobject.c	Sat Dec 20 14:23:02 2008
@@ -2232,14 +2232,45 @@
 	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

Modified: python/branches/release30-maint/Objects/unicodeobject.c
==============================================================================
--- python/branches/release30-maint/Objects/unicodeobject.c	(original)
+++ python/branches/release30-maint/Objects/unicodeobject.c	Sat Dec 20 14:23:02 2008
@@ -6508,81 +6508,65 @@
     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,


More information about the Python-checkins mailing list