Skip to content

Commit 2a8edba

Browse files
authored
Merge pull request #517 from eulerkochy/bench-robindict
comprehensive benchmark suite for AbstractDict
2 parents e3c9c56 + acbff11 commit 2a8edba

File tree

1 file changed

+46
-226
lines changed

1 file changed

+46
-226
lines changed

test/bench_robin_dict.jl

Lines changed: 46 additions & 226 deletions
Original file line numberDiff line numberDiff line change
@@ -1,227 +1,47 @@
1-
using BenchmarkTools, Random, DataStructures, Printf, Plots, Statistics
2-
3-
include("../src/robin_dict.jl")
4-
5-
function add_entries(h::AbstractDict, entries::Vector{Pair{K, V}}) where {K, V}
6-
for (k, v) in entries
7-
h[k] = v
8-
end
9-
end
10-
11-
@printf(".\nSample #1 Key => Integer , Size => 10^6 entries\n.\n")
12-
13-
sample1 = rand(Int, 10^6, 2)
14-
entries1 = Vector{Pair{Int, Int}}()
15-
sizehint!(entries1, 10^6)
16-
for i = 1 : 10^6
17-
push!(entries1, Pair{Int, Int}(sample1[i, 1], sample1[i, 2]))
18-
end
19-
20-
@printf(" add_entries for RobinDict()\n")
21-
@btime add_entries(RobinDict(), entries1)
22-
23-
@printf(" add_entries for Dict()\n")
24-
@btime add_entries(Dict(), entries1)
25-
26-
@printf(" add_entries for RobinDict{Int, Int}()\n")
27-
@btime add_entries(RobinDict{Int, Int}(), entries1)
28-
29-
@printf(" add_entries for Dict{Int, Int}()\n")
30-
@btime add_entries(Dict{Int, Int}(), entries1)
31-
32-
@printf(".\nSample #2 Key => Float32 , Size => 10^6 entries\n.\n")
33-
34-
sample2 = rand(Float32, 10^6, 2)
35-
entries2 = Vector{Pair{Float32, Float32}}()
36-
sizehint!(entries2, 10^6)
37-
for i = 1 : 10^6
38-
push!(entries2, Pair{Float32, Float32}(sample1[i, 1], sample1[i, 2]))
39-
end
40-
41-
@printf(" add_entries for RobinDict()\n")
42-
@btime add_entries(RobinDict(), entries2)
43-
44-
@printf(" add_entries for Dict()\n")
45-
@btime add_entries(Dict(), entries2)
46-
47-
@printf(" add_entries for RobinDict{Float32, Float32}()\n")
48-
@btime add_entries(RobinDict{Float32, Float32}(), entries2)
49-
50-
@printf(" add_entries for Dict{Float32, Float32}()\n")
51-
@btime add_entries(Dict{Float32, Float32}(), entries2)
52-
53-
54-
55-
@printf(".\nSample #3 Key => String , Size => 10^6 entries\n.\n")
56-
57-
entries3 = Vector{Pair{String, String}}()
58-
sizehint!(entries3, 10^6)
59-
for i = 1 : 10^6
60-
push!(entries3, Pair{String, String}(randstring(), randstring()))
1+
using DataStructures
2+
using OrderedCollections
3+
using BenchmarkTools
4+
using Random
5+
6+
suite = BenchmarkGroup()
7+
8+
dicttypes = [Dict, RobinDict]
9+
KVtypes = [Int, Float64]
10+
aexps = [4]
11+
for dt in dicttypes
12+
for aexp in aexps
13+
for K in KVtypes
14+
V = K
15+
Random.seed!(0)
16+
sample = rand(K, 10^aexp, 2)
17+
entries = [sample[i, 1]=>sample[i, 2] for i in 1:size(sample, 1)]
18+
sample_str = string(" 10^$aexp elem $K")
19+
20+
dict = (dt == Dict) ? string("base-Dict") : string(dt)
21+
22+
# dict_el_type: {Any, Any}
23+
suite["make "*dict*"()"*sample_str] = @benchmarkable $(dt)($entries)
24+
suite["pop! "*dict*"()"*sample_str] = @benchmarkable pop!(h) setup=(h=$(dt)($entries))
25+
suite["empty! "*dict*"()"*sample_str] = @benchmarkable empty!(h) setup=(h=$(dt)($entries))
26+
suite["find-success "*dict*"()"*sample_str] = @benchmarkable get(h, e, -1) setup=(h=$(dt)($entries); e=($entries)[1, 1])
27+
suite["find-failure "*dict*"()"*sample_str] = @benchmarkable get(h, e, -1) setup=(h=$(dt)($entries); e=first(pop!(h)))
28+
# dict_el_type: {K, V}
29+
suite["make "*dict*"{$K,$V}()"*sample_str] = @benchmarkable $(dt){$K,$V}($entries)
30+
suite["pop! "*dict*"{$K,$V}()"*sample_str] = @benchmarkable pop!(h) setup=(h=$(dt){$K,$V}($entries))
31+
suite["empty! "*dict*"{$K,$V}()"*sample_str] = @benchmarkable empty!(h) setup=(h=$(dt){$K,$V}($entries))
32+
suite["find-success "*dict*"{$K,$V}()"*sample_str] = @benchmarkable get(h, e, -1) setup=(h=$(dt){$K,$V}($entries); e=($entries)[1, 1])
33+
suite["find-failure "*dict*"{$K,$V}()"*sample_str] = @benchmarkable get(h, e, -1) setup=(h=$(dt){$K,$V}($entries); e=first(pop!(h)))
34+
end
35+
end
36+
end
37+
38+
results = run(suite, verbose=true);
39+
40+
function filter_result(results, op, dt, apow=4)
41+
dict = (dt == Dict) ? string("base-Dict") : string(dt)
42+
for tr in keys(filter(k->(occursin(op, first(k)) && occursin(dict, first(k))
43+
&& occursin("10^$apow", first(k))) , results))
44+
println(tr, " memory ", memory(results[tr])/1024, " kB")
45+
println(tr, " minimum time ", minimum(results[tr]))
46+
end
6147
end
62-
63-
@printf(" add_entries for RobinDict()\n")
64-
@btime add_entries(RobinDict(), entries3)
65-
66-
@printf(" add_entries for Dict()\n")
67-
@btime add_entries(Dict(), entries3)
68-
69-
@printf(" add_entries for RobinDict{String, String}()\n")
70-
@btime add_entries(RobinDict{String, String}(), entries3)
71-
72-
@printf(" add_entries for Dict{String, String}()\n")
73-
@btime add_entries(Dict{String, String}(), entries3)
74-
75-
@printf(".\nSample #4 Key => Integer , Size => 10^7 entries\n.\n")
76-
77-
sample1 = rand(Int, 10^7, 2)
78-
entries1 = Vector{Pair{Int, Int}}()
79-
sizehint!(entries1, 10^7)
80-
for i = 1 : 10^7
81-
push!(entries1, Pair{Int, Int}(sample1[i, 1], sample1[i, 2]))
82-
end
83-
84-
@printf(" add_entries for RobinDict()\n")
85-
@btime add_entries(RobinDict(), entries1)
86-
87-
@printf(" add_entries for Dict()\n")
88-
@btime add_entries(Dict(), entries1)
89-
90-
@printf(" add_entries for RobinDict{Int, Int}()\n")
91-
@btime add_entries(RobinDict{Int, Int}(), entries1)
92-
93-
@printf(" add_entries for Dict{Int, Int}()\n")
94-
@btime add_entries(Dict{Int, Int}(), entries1)
95-
96-
@printf(".\nSample #5 Key => Integer , Size => 10^5 entries\n.\n")
97-
98-
sample1 = rand(Int, 10^5, 2)
99-
entries1 = Vector{Pair{Int, Int}}()
100-
sizehint!(entries1, 10^5)
101-
for i = 1 : 10^5
102-
push!(entries1, Pair{Int, Int}(sample1[i, 1], sample1[i, 2]))
103-
end
104-
105-
@printf(" add_entries for RobinDict()\n")
106-
@btime add_entries(RobinDict(), entries1)
107-
108-
@printf(" add_entries for Dict()\n")
109-
@btime add_entries(Dict(), entries1)
110-
111-
@printf(" add_entries for RobinDict{Int, Int}()\n")
112-
@btime add_entries(RobinDict{Int, Int}(), entries1)
113-
114-
@printf(" add_entries for Dict{Int, Int}()\n")
115-
@btime add_entries(Dict{Int, Int}(), entries1)
116-
117-
@printf(".\nSample #6 Key => Float32 , Size => 10^5 entries\n.\n")
118-
119-
sample2 = rand(Float32, 10^5, 2)
120-
entries2 = Vector{Pair{Float32, Float32}}()
121-
sizehint!(entries2, 10^5)
122-
for i = 1 : 10^5
123-
push!(entries2, Pair{Float32, Float32}(sample1[i, 1], sample1[i, 2]))
124-
end
125-
126-
@printf(" add_entries for RobinDict()\n")
127-
@btime add_entries(RobinDict(), entries2)
128-
129-
@printf(" add_entries for Dict()\n")
130-
@btime add_entries(Dict(), entries2)
131-
132-
@printf(" add_entries for RobinDict{Float32, Float32}()\n")
133-
@btime add_entries(RobinDict{Float32, Float32}(), entries2)
134-
135-
@printf(" add_entries for Dict{Float32, Float32}()\n")
136-
@btime add_entries(Dict{Float32, Float32}(), entries2)
137-
138-
139-
140-
@printf(".\nSample #7 Key => String , Size => 10^5 entries\n.\n")
141-
142-
entries3 = Vector{Pair{String, String}}()
143-
sizehint!(entries3, 10^5)
144-
for i = 1 : 10^5
145-
push!(entries3, Pair{String, String}(randstring(), randstring()))
146-
end
147-
148-
@printf(" add_entries for RobinDict()\n")
149-
@btime add_entries(RobinDict(), entries3)
150-
151-
@printf(" add_entries for Dict()\n")
152-
@btime add_entries(Dict(), entries3)
153-
154-
@printf(" add_entries for RobinDict{String, String}()\n")
155-
@btime add_entries(RobinDict{String, String}(), entries3)
156-
157-
@printf(" add_entries for Dict{String, String}()\n")
158-
@btime add_entries(Dict{String, String}(), entries3)
159-
160-
161-
## Plots
162-
163-
get_load_factor(h::AbstractDict) = (h.count / length(h.keys))
164-
165-
function get_mean_dibs(h::RobinDict)
166-
sz = length(h.keys)
167-
dibs = zeros(Int8, sz)
168-
for i = 1:sz
169-
if isslotfilled(h, i)
170-
dibs[i] = calculate_distance(h, i)
171-
end
172-
end
173-
mean(dibs)
174-
end
175-
176-
function get_variance_dibs(h::RobinDict)
177-
sz = length(h.keys)
178-
dibs = zeros(Int8, sz)
179-
for i = 1:sz
180-
if isslotfilled(h, i)
181-
dibs[i] = calculate_distance(h, i)
182-
end
183-
end
184-
var(dibs)
185-
end
186-
187-
function plot_helper_add_entries(h::RobinDict, entries::Vector{Pair{K, V}}) where {K, V}
188-
num = 0
189-
sz = length(entries)
190-
sq = floor(sqrt(sz))
191-
x = Int[]
192-
lf = Float32[]
193-
xx = Int[]
194-
mean_dibs = Float32[]
195-
var_dibs = Float32[]
196-
for (k, v) in entries
197-
push!(x, num)
198-
push!(lf, get_load_factor(h))
199-
if (num % sq == 0)
200-
push!(mean_dibs, get_mean_dibs(h))
201-
push!(var_dibs, get_variance_dibs(h))
202-
push!(xx, num)
203-
end
204-
h[k] = v
205-
num += 1
206-
end
207-
push!(x, num)
208-
push!(lf, get_load_factor(h))
209-
if (num % sq == 0)
210-
push!(mean_dibs, get_mean_dibs(h))
211-
push!(var_dibs, get_variance_dibs(h))
212-
push!(xx, num)
213-
end
214-
y = [lf]
215-
yy = [mean_dibs var_dibs]
216-
png(plot(x, y, label = ["Load Factor"]), "lf_$(Int(sz/1000))K @$(ROBIN_DICT_LOAD_FACTOR) L.F")
217-
png(plot(xx, yy, label = ["mean(DIB)", "var(DIB)"]), "dibs_$(Int(sz/1000))K @$(ROBIN_DICT_LOAD_FACTOR) L.F")
218-
end
219-
220-
sample1 = rand(Int, 10^6, 2)
221-
entries1 = Vector{Pair{Int, Int}}()
222-
sizehint!(entries1, 10^6)
223-
for i = 1 : 10^6
224-
push!(entries1, Pair{Int, Int}(sample1[i, 1], sample1[i, 2]))
225-
end
226-
227-
plot_helper_add_entries(RobinDict{Int, Int}(), entries1)

0 commit comments

Comments
 (0)