Skip to content

Commit

Permalink
Enhancement: Add a custom initial allocation size for typed dicts.
Browse files Browse the repository at this point in the history
See numba#8110
The new 'allocated' parameter in Dict.empty() is the number of entries the dictionary
should take without requiring a resize.
  • Loading branch information
stefanfed committed Jun 19, 2022
1 parent 6ed0fd0 commit 078c701
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 0 deletions.
1 change: 1 addition & 0 deletions numba/_helpermod.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ build_c_helpers_dict(void)

/* for dictionary support */
declmethod(test_dict);
declmethod(dict_new);
declmethod(dict_new_minsize);
declmethod(dict_set_method_table);
declmethod(dict_free);
Expand Down
26 changes: 26 additions & 0 deletions numba/cext/dictobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,24 @@ int mem_cmp_zeros(void *obj, size_t n){
#define D_MASK(dk) ((dk)->size-1)
#define D_GROWTH_RATE(d) ((d)->used*3)


/* Gets the next power of 2 greater than val
This fails when result is 2^(8*sizeof(Py_ssize_t)-2) due to sign
Could pose a real problem on 32-bit systems */
Py_ssize_t next_pow2_greater_than(Py_ssize_t val) {
val--;

uint32_t shift;
for (shift = 1; shift < sizeof(Py_ssize_t) * CHAR_BIT; shift <<= 1) {
val |= (val >> shift);
}

val++;

return val;
}


static int
ix_size(Py_ssize_t size) {
if ( size < 0xff ) return 1;
Expand Down Expand Up @@ -368,6 +386,7 @@ set_index(NB_DictKeys *dk, Py_ssize_t i, Py_ssize_t ix)
* USABLE_FRACTION should be quick to calculate.
* Fractions around 1/2 to 2/3 seem to work well in practice.
*/

#define USABLE_FRACTION(n) (((n) << 1)/3)

/* Alternative fraction that is otherwise close enough to 2n/3 to make
Expand Down Expand Up @@ -543,6 +562,13 @@ int
numba_dict_new(NB_Dict **out, Py_ssize_t size, Py_ssize_t key_size, Py_ssize_t val_size) {
NB_DictKeys* dk;
NB_Dict *d;

// Should the minsize case reimplement numba_dict_new without this part?
if (size != D_MINSIZE){
size += (size >> 1); // Relies on a usable fraction of 2/3.
size = next_pow2_greater_than(size);
}

int status = numba_dictkeys_new(&dk, size, key_size, val_size);
if (status != OK) return status;

Expand Down

0 comments on commit 078c701

Please sign in to comment.