8000 dict: Use DK_LOG_SIZE in hot loop. (GH-31405) · python/cpython@5543d9c · GitHub
[go: up one dir, main page]

Skip to content

Commit 5543d9c

Browse files
authored
dict: Use DK_LOG_SIZE in hot loop. (GH-31405)
DK_LOG_SIZE(key) < 8 is faster than DK_SIZE(key) <= 0xff, at least on GCC.
1 parent 99331fc commit 5543d9c

File tree

1 file changed

+12
-12
lines changed

1 file changed

+12
-12
lines changed

Objects/dictobject.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -320,19 +320,19 @@ dictkeys_decref(PyDictKeysObject *dk)
320320
static inline Py_ssize_t
321321
dictkeys_get_index(const PyDictKeysObject *keys, Py_ssize_t i)
322322
{
323-
Py_ssize_t s = DK_SIZE(keys);
323+
int log2size = DK_LOG_SIZE(keys);
324324
Py_ssize_t ix;
325325

326-
if (s <= 0xff) {
326+
if (log2size < 8) {
327327
const int8_t *indices = (const int8_t*)(keys->dk_indices);
328328
ix = indices[i];
329329
}
330-
else if (s <= 0xffff) {
330+
else if (log2size < 16) {
331331
const int16_t *indices = (const int16_t*)(keys->dk_indices);
332332
ix = indices[i];
333333
}
334334
#if SIZEOF_VOID_P > 4
335-
else if (s > 0xffffffff) {
335+
else if (log2size >= 32) {
336336
const int64_t *indices = (const int64_t*)(keys->dk_indices);
337337
ix = indices[i];
338338
}
@@ -349,23 +349,23 @@ dictkeys_get_index(const PyDictKeysObject *keys, Py_ssize_t i)
349349
static inline void
350350
dictkeys_set_index(PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix)
351351
{
352-
Py_ssize_t s = DK_SIZE(keys);
352+
int log2size = DK_LOG_SIZE(keys);
353353

354354
assert(ix >= DKIX_DUMMY);
355355
assert(keys->dk_version == 0);
356356

357-
if (s <= 0xff) {
357+
if (log2size < 8) {
358358
int8_t *indices = (int8_t*)(keys->dk_indices);
359359
assert(ix <= 0x7f);
360360
indices[i] = (char)ix;
361361
}
362-
else if (s <= 0xffff) {
362+
else if (log2size < 16) {
363363
int16_t *indices = (int16_t*)(keys->dk_indices);
364364
assert(ix <= 0x7fff);
365365
indices[i] = (int16_t)ix;
366366
}
367367
#if SIZEOF_VOID_P > 4
368-
else if (s > 0xffffffff) {
368+
else if (log2size >= 32) {
369369
int64_t *indices = (int64_t*)(keys->dk_indices);
370370
indices[i] = ix;
371371
}
@@ -631,7 +631,7 @@ free_keys_object(PyDictKeysObject *keys)
631631
// free_keys_object() must not be called after _PyDict_Fini()
632632
assert(state->keys_numfree != -1);
633633
#endif
634-
if (DK_SIZE(keys) == PyDict_MINSIZE && state->keys_numfree < PyDict_MAXFREELIST) {
634+
if (DK_LOG_SIZE(keys) == PyDict_LOG_MINSIZE && state->keys_numfree < PyDict_MAXFREELIST) {
635635
state->keys_free_list[state->keys_numfree++] = keys;
636636
return;
637637
}
@@ -1196,7 +1196,7 @@ Internal routine used by dictresize() to build a hashtable of entries.
11961196
static void
11971197
build_indices(PyDictKeysObject *keys, PyDictKeyEntry *ep, Py_ssize_t n)
11981198
{
1199-
size_t mask = (size_t)DK_SIZE(keys) - 1;
1199+
size_t mask = DK_MASK(keys);
12001200
for (Py_ssize_t ix = 0; ix != n; ix++, ep++) {
12011201
Py_hash_t hash = ep->me_hash;
12021202
size_t i = hash & mask;
@@ -1296,7 +1296,7 @@ dictresize(PyDictObject *mp, uint8_t log2_newsize)
12961296
// dictresize() must not be called after _PyDict_Fini()
12971297
assert(state->keys_numfree != -1);
12981298
#endif
1299-
if (DK_SIZE(oldkeys) == PyDict_MINSIZE &&
1299+
if (DK_LOG_SIZE(oldkeys) == PyDict_LOG_MINSIZE &&
13001300
state->keys_numfree < PyDict_MAXFREELIST)
13011301
{
13021302
state->keys_free_list[state->keys_numfree++] = oldkeys;
@@ -2555,7 +2555,7 @@ dict_merge(PyObject *a, PyObject *b, int override)
25552555
// If other is clean, combined, and just allocated, just clone it.
25562556
if (other->ma_values == NULL &&
25572557
other->ma_used == okeys->dk_nentries &&
2558-
(DK_SIZE(okeys) == PyDict_MINSIZE ||
2558+
(DK_LOG_SIZE(okeys) == PyDict_LOG_MINSIZE ||
25592559
USABLE_FRACTION(DK_SIZE(okeys)/2) < other->ma_used)) {
25602560
PyDictKeysObject *keys = clone_combined_dict_keys(other);
25612561
if (keys == NULL) {

0 commit comments

Comments
 (0)
0