[Python-3000-checkins] r58196 - python/branches/py3k/Objects/unicodeobject.c

guido.van.rossum python-3000-checkins at python.org
Tue Sep 18 21:42:40 CEST 2007


Author: guido.van.rossum
Date: Tue Sep 18 21:42:40 2007
New Revision: 58196

Modified:
   python/branches/py3k/Objects/unicodeobject.c
Log:
Optimize unicode_hash() by not calling
_PyUnicode_AsDefaultEncodedString() at all -- this saves two object
allocations (three block allocations!)  and lots of redundant work.
By using the same hash algorithm as string_hash(), we maintain the
invariant that the hash of an ASCII string is the same whether
represented as a PyString or a PyUnicode.


Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c	(original)
+++ python/branches/py3k/Objects/unicodeobject.c	Tue Sep 18 21:42:40 2007
@@ -6587,21 +6587,27 @@
     return (PyObject*) PyUnicode_FromUnicode(&self->str[index], 1);
 }
 
+/* Believe it or not, this produces the same value for ASCII strings
+   as string_hash(). */
 static long
 unicode_hash(PyUnicodeObject *self)
 {
-    if (self->hash != -1) {
-	return self->hash;
-    }
-    else {
-        /* Since Unicode objects compare equal to their UTF-8 string
-           counterparts, we hash the UTF-8 string. */
-        PyObject *v = _PyUnicode_AsDefaultEncodedString((PyObject*)self, NULL);
-        if (v == NULL)
-            return -1;
-        assert(PyString_CheckExact(v));
-        return self->hash = v->ob_type->tp_hash(v);
-    }
+    Py_ssize_t len;
+    Py_UNICODE *p;
+    long x;
+
+    if (self->hash != -1)
+        return self->hash;
+    len = Py_Size(self);
+    p = self->str;
+    x = *p << 7;
+    while (--len >= 0)
+        x = (1000003*x) ^ *p++;
+    x ^= Py_Size(self);
+    if (x == -1)
+        x = -2;
+    self->hash = x;
+    return x;
 }
 
 PyDoc_STRVAR(index__doc__,


More information about the Python-3000-checkins mailing list