diff options
author | Raymond Hettinger <python@rcn.com> | 2015-01-26 00:12:49 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2015-01-26 00:12:49 (GMT) |
commit | 93035c44fd49359e47947fa23aded502d3a4155e (patch) | |
tree | 0379a5afd7ba7ca33e719632261bf05dfd5b385f /Objects | |
parent | bbd3aa8ece3ed4caf98158086c4599248eb9cddf (diff) | |
download | cpython-93035c44fd49359e47947fa23aded502d3a4155e.zip cpython-93035c44fd49359e47947fa23aded502d3a4155e.tar.gz cpython-93035c44fd49359e47947fa23aded502d3a4155e.tar.bz2 |
Issue #23119: Simplify setobject by inlining the special case for unicode equality testing.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/setobject.c | 81 |
1 files changed, 11 insertions, 70 deletions
diff --git a/Objects/setobject.c b/Objects/setobject.c index ddf6822..f789434 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -69,6 +69,10 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash) PyObject *startkey = entry->key; if (startkey == key) return entry; + if (PyUnicode_CheckExact(startkey) + && PyUnicode_CheckExact(key) + && unicode_eq(startkey, key)) + return entry; Py_INCREF(startkey); cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); Py_DECREF(startkey); @@ -90,6 +94,10 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash) PyObject *startkey = entry->key; if (startkey == key) return entry; + if (PyUnicode_CheckExact(startkey) + && PyUnicode_CheckExact(key) + && unicode_eq(startkey, key)) + return entry; Py_INCREF(startkey); cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); Py_DECREF(startkey); @@ -116,68 +124,6 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash) } /* - * Hacked up version of set_lookkey which can assume keys are always unicode; - * This means we can always use unicode_eq directly and not have to check to - * see if the comparison altered the table. - */ -static setentry * -set_lookkey_unicode(PySetObject *so, PyObject *key, Py_hash_t hash) -{ - setentry *table = so->table; - setentry *freeslot = NULL; - setentry *entry; - size_t perturb = hash; - size_t mask = so->mask; - size_t i = (size_t)hash; - size_t j; - - /* Make sure this function doesn't have to handle non-unicode keys, - including subclasses of str; e.g., one reason to subclass - strings is to override __eq__, and for speed we don't cater to - that here. */ - if (!PyUnicode_CheckExact(key)) { /* unlikely */ - so->lookup = set_lookkey; - return set_lookkey(so, key, hash); - } - - entry = &table[i & mask]; - if (entry->key == NULL) - return entry; - - while (1) { - if (entry->hash == hash - && (entry->key == key - || (entry->key != dummy /* unlikely */ - && unicode_eq(entry->key, key)))) /* likely */ - return entry; - if (entry->key == dummy && freeslot == NULL) - freeslot = entry; - - for (j = 1 ; j <= LINEAR_PROBES ; j++) { - entry = &table[(i + j) & mask]; - if (entry->key == NULL) - goto found_null; - if (entry->hash == hash - && (entry->key == key - || (entry->key != dummy /* unlikely */ - && unicode_eq(entry->key, key)))) /* likely */ - return entry; - if (entry->key == dummy && freeslot == NULL) - freeslot = entry; - } - - perturb >>= PERTURB_SHIFT; - i = i * 5 + 1 + perturb; - - entry = &table[i & mask]; - if (entry->key == NULL) - goto found_null; - } - found_null: - return freeslot == NULL ? entry : freeslot; -} - -/* Internal routine used by set_table_resize() to insert an item which is known to be absent from the set. This routine also assumes that the set contains no deleted entries. Besides the performance benefit, @@ -225,8 +171,7 @@ set_insert_key(PySetObject *so, PyObject *key, Py_hash_t hash) { setentry *entry; - assert(so->lookup != NULL); - entry = so->lookup(so, key, hash); + entry = set_lookkey(so, key, hash); if (entry == NULL) return -1; if (entry->key == NULL) { @@ -385,7 +330,7 @@ set_discard_entry(PySetObject *so, setentry *oldentry) setentry *entry; PyObject *old_key; - entry = (so->lookup)(so, oldentry->key, oldentry->hash); + entry = set_lookkey(so, oldentry->key, oldentry->hash); if (entry == NULL) return -1; if (entry->key == NULL || entry->key == dummy) @@ -631,7 +576,7 @@ set_contains_entry(PySetObject *so, setentry *entry) PyObject *key; setentry *lu_entry; - lu_entry = (so->lookup)(so, entry->key, entry->hash); + lu_entry = set_lookkey(so, entry->key, entry->hash); if (lu_entry == NULL) return -1; key = lu_entry->key; @@ -994,7 +939,6 @@ make_new_set(PyTypeObject *type, PyObject *iterable) so->used = 0; so->mask = PySet_MINSIZE - 1; so->table = so->smalltable; - so->lookup = set_lookkey_unicode; so->hash = -1; so->finger = 0; so->weakreflist = NULL; @@ -1095,7 +1039,6 @@ set_swap_bodies(PySetObject *a, PySetObject *b) { Py_ssize_t t; setentry *u; - setentry *(*f)(PySetObject *so, PyObject *key, Py_ssize_t hash); setentry tab[PySet_MINSIZE]; Py_hash_t h; @@ -1111,8 +1054,6 @@ set_swap_bodies(PySetObject *a, PySetObject *b) a->table = a->smalltable; b->table = u; - f = a->lookup; a->lookup = b->lookup; b->lookup = f; - if (a->table == a->smalltable || b->table == b->smalltable) { memcpy(tab, a->smalltable, sizeof(tab)); memcpy(a->smalltable, b->smalltable, sizeof(tab)); |