Here are some benchmarks about how expensive is to update/modify a Map in Elixir, with three sizes.
This was done in the context of implementing a Raft-backed prototyping database,
tentatively called hako 箱 .
based on the Ra
library!
def large_maps_benchmark do
Benchee.run(
%{
"put" => fn input -> Map.put(input, "testillo", 14) end,
"update" => fn input -> Map.update(input, "testillo", 9, &(&1 + 5)) end,
"update!" => fn input -> Map.update!(input, "testillo", &(&1 + 5)) end,
"merge" => fn input -> Map.merge(input, %{"testillo" => 14}) end,
},
time: 5,
inputs: %{
"Small(10~)" => gen_map(10),
"Medium(1000~)" => gen_map(1000),
"Large(10000~)" => gen_map(10000),
"XLarge(100000~)" => gen_map(100000),
"Ginormous(1000000~)" => gen_map(1000000),
}
)
:ok
end
def gen_map(size) do
Enum.reduce(1..size, %{}, fn _, acc ->
key = "key_#{:crypto.strong_rand_bytes(5) |> Base.encode16()}"
value = :rand.uniform(1000)
Map.put(acc, key, value)
end)
|> Map.put("testillo", 9)
end
##### With input Ginormous(1000000~) #####
Name ips average deviation median 99th %
put 3.56 M 281.05 ns ±754.64% 259 ns 1473 ns
merge 1.94 M 516.79 ns ±336.31% 278 ns 2671 ns
update! 1.74 M 573.18 ns ±6933.88% 326 ns 2642 ns
update 1.73 M 577.18 ns ±6354.57% 322 ns 2651 ns
Comparison:
put 3.56 M
merge 1.94 M - 1.84x slower +235.73 ns
update! 1.74 M - 2.04x slower +292.12 ns
update 1.73 M - 2.05x slower +296.13 ns
##### With input Large(10000~) #####
Name ips average deviation median 99th %
put 5.07 M 197.38 ns ±8790.74% 178 ns 274 ns
merge 4.95 M 201.93 ns ±9680.25% 180 ns 336 ns
update 3.41 M 293.49 ns ±10653.99% 236 ns 320 ns
update! 3.34 M 299.45 ns ±10613.89% 235 ns 349 ns
Comparison:
put 5.07 M
merge 4.95 M - 1.02x slower +4.55 ns
update 3.41 M - 1.49x slower +96.11 ns
update! 3.34 M - 1.52x slower +102.07 ns
##### With input Medium(1000~) #####
Name ips average deviation median 99th %
put 5.93 M 168.57 ns ±162.94% 161 ns 234 ns
merge 5.76 M 173.61 ns ±153.90% 162 ns 292 ns
update! 4.55 M 220.00 ns ±2470.22% 209 ns 282 ns
update 4.51 M 221.58 ns ±2450.85% 209 ns 305 ns
Comparison:
put 5.93 M
merge 5.76 M - 1.03x slower +5.05 ns
update! 4.55 M - 1.31x slower +51.43 ns
update 4.51 M - 1.31x slower +53.02 ns
##### With input Small(10~) #####
Name ips average deviation median 99th %
update 3.50 M 285.96 ns ±12054.42% 254 ns 318 ns
update! 3.47 M 288.19 ns ±12696.49% 256 ns 331 ns
put 3.01 M 332.06 ns ±12540.52% 238 ns 302 ns
merge 3.00 M 332.79 ns ±11905.64% 239 ns 429 ns
Comparison:
update 3.50 M
update! 3.47 M - 1.01x slower +2.23 ns
put 3.01 M - 1.16x slower +46.10 ns
merge 3.00 M - 1.16x slower +46.83 ns
##### With input XLarge(100000~) #####
Name ips average deviation median 99th %
put 3.93 M 254.73 ns ±549.90% 245 ns 356 ns
merge 3.92 M 255.24 ns ±487.38% 245 ns 409 ns
update 2.71 M 368.99 ns ±5945.52% 292 ns 493 ns
update! 2.57 M 388.52 ns ±5406.10% 298 ns 601 ns
Comparison:
put 3.93 M
merge 3.92 M - 1.00x slower +0.50 ns
update 2.71 M - 1.45x slower +114.26 ns
update! 2.57 M - 1.53x slower +133.79 ns