Skip to content

Commit

Permalink
Make empty Dict only have space for 0 rather than 16 elements (and …
Browse files Browse the repository at this point in the history
…the minimum size for non-empty `Dict` down to 4). (#52912)

This improves speed and reduces allocation for small Dicts.
```
#before
julia> @Btime Dict{Int,Int}()
  46.815 ns (4 allocations: 448 bytes)

#after
julia> @Btime Dict{Int, Int}()
  9.429 ns (1 allocation: 80 bytes)
```
The initialization to 16 before made sense when `Dict` was `Vector`
backed since `Vectors` were slow to instantiate, but Memory is much
faster).
  • Loading branch information
oscardssmith committed Jan 23, 2024
1 parent 4dcd271 commit d741c24
Showing 1 changed file with 9 additions and 4 deletions.
13 changes: 9 additions & 4 deletions base/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ mutable struct Dict{K,V} <: AbstractDict{K,V}
maxprobe::Int

function Dict{K,V}() where V where K
n = 16
n = 0
slots = Memory{UInt8}(undef,n)
fill!(slots, 0x0)
new(slots, Memory{K}(undef, n), Memory{V}(undef, n), 0, 0, 0, n, 0)
new(slots, Memory{K}(undef, n), Memory{V}(undef, n), 0, 0, 0, max(1, n), 0)
end
function Dict{K,V}(d::Dict{K,V}) where V where K
new(copy(d.slots), copy(d.keys), copy(d.vals), d.ndel, d.count, d.age,
Expand Down Expand Up @@ -266,7 +266,7 @@ function empty!(h::Dict{K,V}) where V where K
h.count = 0
h.maxprobe = 0
h.age += 1
h.idxfloor = sz
h.idxfloor = max(1, sz)
return h
end

Expand Down Expand Up @@ -302,6 +302,11 @@ end
# This version is for use by setindex! and get!
function ht_keyindex2_shorthash!(h::Dict{K,V}, key) where V where K
sz = length(h.keys)
if sz == 0 # if Dict was empty resize and then return location to insert
rehash!(h, 4)
index, sh = hashindex(key, length(h.keys))
return -index, sh
end
iter = 0
maxprobe = h.maxprobe
index, sh = hashindex(key, sz)
Expand Down Expand Up @@ -367,7 +372,7 @@ ht_keyindex2!(h::Dict, key) = ht_keyindex2_shorthash!(h, key)[1]
# Rehash now if necessary
if (h.count + h.ndel)*3 > sz*2
# > 2/3 full (including tombstones)
rehash!(h, h.count > 64000 ? h.count*2 : h.count*4)
rehash!(h, h.count > 64000 ? h.count*2 : max(h.count*4, 4))
end
nothing
end
Expand Down

0 comments on commit d741c24

Please sign in to comment.