bpo-29202: improve dict iteration (GH-11900)

Use fewer iterations instead of iterating over the whole entry table.
This commit is contained in:
Cheryl Sabella 2019-04-05 06:08:43 -04:00 committed by Inada Naoki
parent 6a8c3139ae
commit f66e336f45
1 changed files with 6 additions and 9 deletions

View File

@ -2147,7 +2147,7 @@ dict_keys(PyDictObject *mp)
PyObject *v; PyObject *v;
Py_ssize_t i, j; Py_ssize_t i, j;
PyDictKeyEntry *ep; PyDictKeyEntry *ep;
Py_ssize_t size, n, offset; Py_ssize_t n, offset;
PyObject **value_ptr; PyObject **value_ptr;
again: again:
@ -2163,7 +2163,6 @@ dict_keys(PyDictObject *mp)
goto again; goto again;
} }
ep = DK_ENTRIES(mp->ma_keys); ep = DK_ENTRIES(mp->ma_keys);
size = mp->ma_keys->dk_nentries;
if (mp->ma_values) { if (mp->ma_values) {
value_ptr = mp->ma_values; value_ptr = mp->ma_values;
offset = sizeof(PyObject *); offset = sizeof(PyObject *);
@ -2172,7 +2171,7 @@ dict_keys(PyDictObject *mp)
value_ptr = &ep[0].me_value; value_ptr = &ep[0].me_value;
offset = sizeof(PyDictKeyEntry); offset = sizeof(PyDictKeyEntry);
} }
for (i = 0, j = 0; i < size; i++) { for (i = 0, j = 0; j < n; i++) {
if (*value_ptr != NULL) { if (*value_ptr != NULL) {
PyObject *key = ep[i].me_key; PyObject *key = ep[i].me_key;
Py_INCREF(key); Py_INCREF(key);
@ -2191,7 +2190,7 @@ dict_values(PyDictObject *mp)
PyObject *v; PyObject *v;
Py_ssize_t i, j; Py_ssize_t i, j;
PyDictKeyEntry *ep; PyDictKeyEntry *ep;
Py_ssize_t size, n, offset; Py_ssize_t n, offset;
PyObject **value_ptr; PyObject **value_ptr;
again: again:
@ -2207,7 +2206,6 @@ dict_values(PyDictObject *mp)
goto again; goto again;
} }
ep = DK_ENTRIES(mp->ma_keys); ep = DK_ENTRIES(mp->ma_keys);
size = mp->ma_keys->dk_nentries;
if (mp->ma_values) { if (mp->ma_values) {
value_ptr = mp->ma_values; value_ptr = mp->ma_values;
offset = sizeof(PyObject *); offset = sizeof(PyObject *);
@ -2216,7 +2214,7 @@ dict_values(PyDictObject *mp)
value_ptr = &ep[0].me_value; value_ptr = &ep[0].me_value;
offset = sizeof(PyDictKeyEntry); offset = sizeof(PyDictKeyEntry);
} }
for (i = 0, j = 0; i < size; i++) { for (i = 0, j = 0; j < n; i++) {
PyObject *value = *value_ptr; PyObject *value = *value_ptr;
value_ptr = (PyObject **)(((char *)value_ptr) + offset); value_ptr = (PyObject **)(((char *)value_ptr) + offset);
if (value != NULL) { if (value != NULL) {
@ -2234,7 +2232,7 @@ dict_items(PyDictObject *mp)
{ {
PyObject *v; PyObject *v;
Py_ssize_t i, j, n; Py_ssize_t i, j, n;
Py_ssize_t size, offset; Py_ssize_t offset;
PyObject *item, *key; PyObject *item, *key;
PyDictKeyEntry *ep; PyDictKeyEntry *ep;
PyObject **value_ptr; PyObject **value_ptr;
@ -2265,7 +2263,6 @@ dict_items(PyDictObject *mp)
} }
/* Nothing we do below makes any function calls. */ /* Nothing we do below makes any function calls. */
ep = DK_ENTRIES(mp->ma_keys); ep = DK_ENTRIES(mp->ma_keys);
size = mp->ma_keys->dk_nentries;
if (mp->ma_values) { if (mp->ma_values) {
value_ptr = mp->ma_values; value_ptr = mp->ma_values;
offset = sizeof(PyObject *); offset = sizeof(PyObject *);
@ -2274,7 +2271,7 @@ dict_items(PyDictObject *mp)
value_ptr = &ep[0].me_value; value_ptr = &ep[0].me_value;
offset = sizeof(PyDictKeyEntry); offset = sizeof(PyDictKeyEntry);
} }
for (i = 0, j = 0; i < size; i++) { for (i = 0, j = 0; j < n; i++) {
PyObject *value = *value_ptr; PyObject *value = *value_ptr;
value_ptr = (PyObject **)(((char *)value_ptr) + offset); value_ptr = (PyObject **)(((char *)value_ptr) + offset);
if (value != NULL) { if (value != NULL) {