Last active
December 18, 2021 03:34
-
-
Save c4710n/474a933e132c212453912dca779bc184 to your computer and use it in GitHub Desktop.
Benchmark - traverse map with `set` and `get` operation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Mix.install([ | |
{:traverse, "~> 1.0"}, | |
{:benchee, "~> 1.0"} | |
]) | |
defmodule Data do | |
def create_sample(count) do | |
sample = %{ | |
user_id: 1, | |
children: [ | |
%{ | |
user_id: 11 | |
}, | |
%{ | |
user_id: 12 | |
}, | |
%{ | |
user_id: 13 | |
}, | |
%{ | |
user_id: 14 | |
}, | |
%{ | |
user_id: 15 | |
}, | |
%{ | |
user_id: 16 | |
}, | |
%{ | |
user_id: 17 | |
}, | |
%{ | |
user_id: 18 | |
}, | |
%{ | |
user_id: 19 | |
}, | |
%{ | |
user_id: 20 | |
} | |
] | |
} | |
List.duplicate(sample, count) | |
end | |
end | |
defmodule Nesto do | |
def get(ds, key) do | |
collector = fn | |
map, acc when is_map(map) -> | |
value = Map.get(map, key) | |
if value, do: [value | acc], else: acc | |
_, acc -> | |
acc | |
end | |
Traverse.walk(ds, [], collector) | |
end | |
def put(ds, fun) do | |
mapper = fn | |
map when is_map(map) -> | |
fun.(map) | |
ele -> | |
ele | |
end | |
Traverse.mapall(ds, mapper) | |
end | |
def delete(ds, key) do | |
mapper = fn | |
map when is_map(map) -> | |
Map.delete(map, key) | |
ele -> | |
ele | |
end | |
Traverse.mapall(ds, mapper) | |
end | |
end | |
users = %{ | |
1 => %{user_id: 1, name: "Billy Brown"}, | |
11 => %{user_id: 11, name: "Billy Brown"}, | |
12 => %{user_id: 12, name: "Billy Brown"}, | |
13 => %{user_id: 13, name: "Billy Brown"}, | |
14 => %{user_id: 14, name: "Billy Brown"}, | |
15 => %{user_id: 15, name: "Billy Brown"}, | |
16 => %{user_id: 16, name: "Billy Brown"}, | |
17 => %{user_id: 17, name: "Billy Brown"}, | |
18 => %{user_id: 18, name: "Billy Brown"}, | |
19 => %{user_id: 19, name: "Billy Brown"}, | |
20 => %{user_id: 20, name: "Billy Brown"} | |
} | |
Benchee.run( | |
%{ | |
"Nesto.get" => fn input -> | |
Nesto.get(input, :user_id) | |
end, | |
"Nesto.set" => fn input -> | |
skip_tag = :__disable_traverse__ | |
Nesto.put(input, fn map -> | |
user_id = Map.get(map, :user_id) | |
skip? = Map.get(map, skip_tag) | |
if user_id && !skip? do | |
user = Map.get(users, user_id) | |
if user do | |
# tag user in order to prevent endless loop | |
tagged_user = Map.put(user, skip_tag, true) | |
Map.put(map, :user, tagged_user) | |
else | |
map | |
end | |
else | |
map | |
end | |
end) | |
|> Nesto.delete(skip_tag) | |
end | |
}, | |
time: 30, | |
memory_time: 2, | |
inputs: %{ | |
"XS - 100" => Data.create_sample(10), | |
"SM - 250" => Data.create_sample(25), | |
"MD - 500" => Data.create_sample(50), | |
"LG - 1000" => Data.create_sample(100) | |
} | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Operating System: macOS | |
CPU Information: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz | |
Number of Available Cores: 12 | |
Available memory: 16 GB | |
Elixir 1.12.3 | |
Erlang 24.1.1 | |
Benchmark suite executing with the following configuration: | |
warmup: 2 s | |
time: 30 s | |
memory time: 2 s | |
parallel: 1 | |
inputs: LG - 1000, MD - 500, SM - 250, XS - 100 | |
Estimated total run time: 4.53 min | |
Benchmarking Nesto.get with input LG - 1000... | |
Benchmarking Nesto.get with input MD - 500... | |
Benchmarking Nesto.get with input SM - 250... | |
Benchmarking Nesto.get with input XS - 100... | |
Benchmarking Nesto.set with input LG - 1000... | |
Benchmarking Nesto.set with input MD - 500... | |
Benchmarking Nesto.set with input SM - 250... | |
Benchmarking Nesto.set with input XS - 100... | |
##### With input LG - 1000 ##### | |
Name ips average deviation median 99th % | |
Nesto.get 4.41 K 0.23 ms ±19.18% 0.21 ms 0.41 ms | |
Nesto.set 0.61 K 1.65 ms ±25.81% 1.56 ms 2.88 ms | |
Comparison: | |
Nesto.get 4.41 K | |
Nesto.set 0.61 K - 7.27x slower +1.42 ms | |
Memory usage statistics: | |
Name Memory usage | |
Nesto.get 0.32 MB | |
Nesto.set 2.19 MB - 6.81x memory usage +1.87 MB | |
**All measurements for memory usage were the same** | |
##### With input MD - 500 ##### | |
Name ips average deviation median 99th % | |
Nesto.get 8.76 K 114.12 μs ±30.13% 105.99 μs 234.99 μs | |
Nesto.set 1.15 K 868.94 μs ±40.93% 786.99 μs 1772.85 μs | |
Comparison: | |
Nesto.get 8.76 K | |
Nesto.set 1.15 K - 7.61x slower +754.82 μs | |
Memory usage statistics: | |
Name Memory usage | |
Nesto.get 0.161 MB | |
Nesto.set 1.09 MB - 6.81x memory usage +0.93 MB | |
**All measurements for memory usage were the same** | |
##### With input SM - 250 ##### | |
Name ips average deviation median 99th % | |
Nesto.get 16.09 K 62.14 μs ±70.89% 56.99 μs 197.99 μs | |
Nesto.set 1.40 K 716.63 μs ±91.67% 464.99 μs 3322.99 μs | |
Comparison: | |
Nesto.get 16.09 K | |
Nesto.set 1.40 K - 11.53x slower +654.49 μs | |
Memory usage statistics: | |
Name Memory usage | |
Nesto.get 82.21 KB | |
Nesto.set 560.51 KB - 6.82x memory usage +478.30 KB | |
**All measurements for memory usage were the same** | |
##### With input XS - 100 ##### | |
Name ips average deviation median 99th % | |
Nesto.get 41.25 K 24.24 μs ±115.16% 19.99 μs 132.99 μs | |
Nesto.set 6.68 K 149.62 μs ±68.04% 126.99 μs 622.99 μs | |
Comparison: | |
Nesto.get 41.25 K | |
Nesto.set 6.68 K - 6.17x slower +125.38 μs | |
Memory usage statistics: | |
Name Memory usage | |
Nesto.get 32.84 KB | |
Nesto.set 224.11 KB - 6.82x memory usage +191.27 KB | |
**All measurements for memory usage were the same** |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment