[Python-checkins] cpython: Optimize PyUnicode_RichCompare() for Py_EQ and Py_NE: always use memcmp()

victor.stinner python-checkins at python.org
Tue Oct 23 03:05:24 CEST 2012


http://hg.python.org/cpython/rev/b68be1025c42
changeset:   79902:b68be1025c42
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Tue Oct 23 02:48:49 2012 +0200
summary:
  Optimize PyUnicode_RichCompare() for Py_EQ and Py_NE: always use memcmp()

files:
  Objects/unicodeobject.c |  74 ++++++++++++++++++----------
  1 files changed, 46 insertions(+), 28 deletions(-)


diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -10296,6 +10296,32 @@
         return 1;
 }
 
+static int
+unicode_compare_eq(PyObject *str1, PyObject *str2)
+{
+    int kind;
+    void *data1, *data2;
+    Py_ssize_t len;
+    int cmp;
+
+    /* a string is equal to itself */
+    if (str1 == str2)
+        return 1;
+
+    len = PyUnicode_GET_LENGTH(str1);
+    if (PyUnicode_GET_LENGTH(str2) != len)
+        return 0;
+    kind = PyUnicode_KIND(str1);
+    if (PyUnicode_KIND(str2) != kind)
+        return 0;
+    data1 = PyUnicode_DATA(str1);
+    data2 = PyUnicode_DATA(str2);
+
+    cmp = memcmp(data1, data2, len * kind);
+    return (cmp == 0);
+}
+
+
 int
 PyUnicode_Compare(PyObject *left, PyObject *right)
 {
@@ -10346,33 +10372,27 @@
 PyUnicode_RichCompare(PyObject *left, PyObject *right, int op)
 {
     int result;
-
-    if (PyUnicode_Check(left) && PyUnicode_Check(right)) {
-        PyObject *v;
-        if (PyUnicode_READY(left) == -1 ||
-            PyUnicode_READY(right) == -1)
-            return NULL;
-        if (PyUnicode_GET_LENGTH(left) != PyUnicode_GET_LENGTH(right) ||
-            PyUnicode_KIND(left) != PyUnicode_KIND(right)) {
-            if (op == Py_EQ) {
-                Py_INCREF(Py_False);
-                return Py_False;
-            }
-            if (op == Py_NE) {
-                Py_INCREF(Py_True);
-                return Py_True;
-            }
-        }
+    PyObject *v;
+
+    if (!PyUnicode_Check(left) || !PyUnicode_Check(right))
+        Py_RETURN_NOTIMPLEMENTED;
+
+    if (PyUnicode_READY(left) == -1 ||
+        PyUnicode_READY(right) == -1)
+        return NULL;
+
+    if (op == Py_EQ || op == Py_NE) {
+        result = unicode_compare_eq(left, right);
+        if (op == Py_EQ)
+            v = TEST_COND(result);
+        else
+            v = TEST_COND(!result);
+    }
+    else {
         result = unicode_compare(left, 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;
@@ -10389,11 +10409,9 @@
             PyErr_BadArgument();
             return NULL;
         }
-        Py_INCREF(v);
-        return v;
-    }
-
-    Py_RETURN_NOTIMPLEMENTED;
+    }
+    Py_INCREF(v);
+    return v;
 }
 
 int

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list