Created
January 15, 2021 10:26
-
-
Save Ljzn/806b0d3d32e8456b9ab92f831042ce7a to your computer and use it in GitHub Desktop.
benchmark BTree vs List
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
defmodule SqlDb do | |
@moduledoc """ | |
# Benchmark of Save and Find | |
Name ips average deviation median 99th % | |
btree 50.43 0.0198 s ±6.77% 0.0197 s 0.0268 s | |
list 0.85 1.18 s ±0.28% 1.17 s 1.18 s | |
Comparison: | |
btree 50.43 | |
list 0.85 - 59.29x slower +1.16 s | |
""" | |
defmodule List do | |
# list | |
def save(db, item) do | |
[item | db] | |
end | |
def find(db, item) do | |
Enum.find(db, fn x -> x == item end) | |
end | |
end | |
defmodule BTree do | |
## btree | |
def save(db, item) do | |
cond do | |
is_min_in_this_layer(db, item) -> | |
if length(db) < 5 do | |
put(db, item) | |
else | |
[leaf | tail] = db | |
[save(leaf, item) | tail] | |
end | |
true -> | |
[leaf, node | tail] = db | |
[leaf, node] ++ save(tail, item) | |
end | |
end | |
defp put([], item), do: [[], item, []] | |
defp put(db, item), do: [[], item | db] | |
# only last leaf | |
defp is_min_in_this_layer([_], _), do: true | |
defp is_min_in_this_layer([], _), do: true | |
defp is_min_in_this_layer([_, node | _], item) when item <= node, do: true | |
defp is_min_in_this_layer(_, _), do: false | |
def find(db, item) do | |
cond do | |
match?([_, ^item | _], db) -> | |
item | |
is_min_in_this_layer(db, item) -> | |
case db do | |
[] -> | |
nil | |
[leaf | _] -> | |
find(leaf, item) | |
end | |
true -> | |
case db do | |
[_, _ | tail] -> | |
find(tail, item) | |
# last leaf | |
[leaf] -> | |
find(leaf, item) | |
end | |
end | |
end | |
end | |
defp test(mod) do | |
sample = | |
for x <- 1..10000 do | |
x | |
end | |
|> Enum.shuffle() | |
db = | |
Enum.reduce(sample, [], fn x, acc -> | |
mod.save(acc, x) | |
end) | |
Enum.each(1..10000, fn x -> | |
^x = mod.find(db, x) | |
end) | |
nil = mod.find(db, -1) | |
end | |
def run do | |
Benchee.run(%{ | |
"list" => fn -> test(List) end, | |
"btree" => fn -> test(BTree) end | |
}) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment