Issue 23359: Tighten inner search loop for sets (don't and-mask every entry lookup).

This commit is contained in:
Raymond Hettinger 2015-02-02 08:35:00 -08:00
parent f86d1fdab7
commit c658d85487
1 changed files with 53 additions and 24 deletions

View File

@ -88,31 +88,60 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
if (entry->key == dummy && freeslot == NULL) if (entry->key == dummy && freeslot == NULL)
freeslot = entry; freeslot = entry;
for (j = 1 ; j <= LINEAR_PROBES ; j++) { if (i + LINEAR_PROBES <= mask) {
entry = &table[(i + j) & mask]; for (j = 1 ; j <= LINEAR_PROBES ; j++) {
if (entry->key == NULL) entry++;
goto found_null; if (entry->key == NULL)
if (entry->hash == hash) { goto found_null;
PyObject *startkey = entry->key; if (entry->hash == hash) {
assert(startkey != dummy); PyObject *startkey = entry->key;
if (startkey == key) assert(startkey != dummy);
return entry; if (startkey == key)
if (PyUnicode_CheckExact(startkey) return entry;
&& PyUnicode_CheckExact(key) if (PyUnicode_CheckExact(startkey)
&& unicode_eq(startkey, key)) && PyUnicode_CheckExact(key)
return entry; && unicode_eq(startkey, key))
Py_INCREF(startkey); return entry;
cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); Py_INCREF(startkey);
Py_DECREF(startkey); cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
if (cmp < 0) Py_DECREF(startkey);
return NULL; if (cmp < 0)
if (table != so->table || entry->key != startkey) return NULL;
return set_lookkey(so, key, hash); if (table != so->table || entry->key != startkey)
if (cmp > 0) return set_lookkey(so, key, hash);
return entry; if (cmp > 0)
return entry;
}
if (entry->key == dummy && freeslot == NULL)
freeslot = entry;
}
} else {
for (j = 1 ; j <= LINEAR_PROBES ; j++) {
entry = &table[(i + j) & mask];
if (entry->key == NULL)
goto found_null;
if (entry->hash == hash) {
PyObject *startkey = entry->key;
assert(startkey != dummy);
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);
if (cmp < 0)
return NULL;
if (table != so->table || entry->key != startkey)
return set_lookkey(so, key, hash);
if (cmp > 0)
return entry;
}
if (entry->key == dummy && freeslot == NULL)
freeslot = entry;
} }
if (entry->key == dummy && freeslot == NULL)
freeslot = entry;
} }
perturb >>= PERTURB_SHIFT; perturb >>= PERTURB_SHIFT;