-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a879e92
commit a141c4b
Showing
11 changed files
with
241 additions
and
1 deletion.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Used by "mix format" | ||
[ | ||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] | ||
] |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# The directory Mix will write compiled artifacts to. | ||
/_build/ | ||
|
||
# If you run "mix test --cover", coverage assets end up here. | ||
/cover/ | ||
|
||
# The directory Mix downloads your dependencies sources to. | ||
/deps/ | ||
|
||
# Where third-party dependencies like ExDoc output generated docs. | ||
/doc/ | ||
|
||
# Ignore .fetch files in case you like to edit your project deps locally. | ||
/.fetch | ||
|
||
# If the VM crashes, it generates a dump, let's ignore it too. | ||
erl_crash.dump | ||
|
||
# Also ignore archive artifacts (built via "mix archive.build"). | ||
*.ez | ||
|
||
# Ignore package tarball (built via "mix hex.build"). | ||
benchmark-*.tar | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Benchmark | ||
|
||
```sh | ||
mix do deps.get, format | ||
mix do compile, benchmark | ||
``` |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
defmodule Benchmark do | ||
@moduledoc """ | ||
""" | ||
|
||
@doc """ | ||
""" | ||
def run do | ||
for test_case <- [Benchmark.Cases.DataStoreKind] do | ||
IO.inspect(test_case) | ||
test_case.run | ||
end | ||
end | ||
end |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
defmodule Benchmark.Cases.DataStoreKind do | ||
@moduledoc """ | ||
Compare the speed of data stores. | ||
""" | ||
|
||
@doc """ | ||
""" | ||
def run do | ||
scenarios = | ||
for name <- ~w(empty ets fast_global gen_server heap persistent_term), into: %{} do | ||
{name, | ||
{ | ||
parallel(fn {param, size} -> | ||
apply(__MODULE__, String.to_existing_atom("run_#{name}"), [param, size]) | ||
end), | ||
before_scenario: fn data -> | ||
{apply(__MODULE__, String.to_existing_atom("prepare_#{name}"), [data]), | ||
map_size(data)} | ||
end, | ||
after_scenario: fn {param, _} -> | ||
apply(__MODULE__, String.to_existing_atom("cleanup_#{name}"), [param]) | ||
end | ||
}} | ||
end | ||
|
||
Benchee.run( | ||
scenarios, | ||
inputs: %{ | ||
"100" => generate_data(100), | ||
"1_000" => generate_data(1_000), | ||
"10_000" => generate_data(10_000), | ||
"100_000" => generate_data(100_000) | ||
}, | ||
memory_time: 2, | ||
time: 10 | ||
) | ||
end | ||
|
||
def prepare_empty(_data), do: nil | ||
|
||
def run_empty(_, size) do | ||
for _ <- 1..100_000, do: :rand.uniform(size) | ||
end | ||
|
||
def cleanup_empty(_), do: nil | ||
|
||
def prepare_ets(data) do | ||
tid = :ets.new(:test, [:set, :protected, read_concurrency: true]) | ||
:ets.insert_new(tid, Map.to_list(data)) | ||
tid | ||
end | ||
|
||
def run_ets(tid, size) do | ||
for _ <- 1..100_000 do | ||
item = :ets.lookup_element(tid, :rand.uniform(size), 2) | ||
item.name | ||
item.callback | ||
end | ||
end | ||
|
||
def cleanup_ets(tid), do: :ets.delete(tid) | ||
|
||
def prepare_fast_global(data) do | ||
data = | ||
for {id, item} <- data, into: %{} do | ||
item = update_in(item.callback, &:erlang.term_to_binary(&1)) | ||
{id, item} | ||
end | ||
|
||
FastGlobal.put(__MODULE__, data) | ||
end | ||
|
||
def run_fast_global(_, size) do | ||
for _ <- 1..100_000 do | ||
item = FastGlobal.get(__MODULE__)[:rand.uniform(size)] | ||
item.name | ||
:erlang.binary_to_term(item.callback) | ||
end | ||
end | ||
|
||
def cleanup_fast_global(_), do: FastGlobal.put(__MODULE__, nil) | ||
|
||
def prepare_gen_server(data), do: elem(GenServer.start_link(__MODULE__.GenServer, data), 1) | ||
|
||
def run_gen_server(pid, size) do | ||
for _ <- 1..100_000 do | ||
item = GenServer.call(pid, {:lookup, :rand.uniform(size)}) | ||
item.name | ||
item.callback | ||
end | ||
end | ||
|
||
def cleanup_gen_server(pid), do: GenServer.stop(pid) | ||
|
||
def prepare_heap(data), do: data | ||
|
||
def run_heap(data, size) do | ||
for _ <- 1..100_000 do | ||
item = data[:rand.uniform(size)] | ||
item.name | ||
item.callback | ||
end | ||
end | ||
|
||
def cleanup_heap(_), do: nil | ||
|
||
def prepare_persistent_term(data), do: :persistent_term.put(__MODULE__, data) | ||
|
||
def run_persistent_term(_, size) do | ||
for _ <- 1..100_000 do | ||
item = :persistent_term.get(__MODULE__)[:rand.uniform(size)] | ||
item.name | ||
item.callback | ||
end | ||
end | ||
|
||
def cleanup_persistent_term(_), do: :persistent_term.erase(__MODULE__) | ||
|
||
defp generate_data(size) do | ||
for i <- 1..size, into: %{} do | ||
item = %{id: i, name: "item #{i}", callback: fn n -> n + 1 end} | ||
{i, item} | ||
end | ||
end | ||
|
||
def parallel(fun) do | ||
fn arg -> | ||
1..System.schedulers_online() | ||
|> Task.async_stream(fn _ -> fun.(arg) end, ordered: false, timeout: 10 * 1000) | ||
|> Stream.run() | ||
end | ||
end | ||
end | ||
|
||
defmodule Benchmark.Cases.DataStoreKind.GenServer do | ||
use GenServer | ||
|
||
@impl GenServer | ||
def init(data), do: {:ok, data} | ||
|
||
@impl GenServer | ||
def handle_call({:lookup, id}, _from, data), do: {:reply, data[id], data} | ||
end |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
defmodule Mix.Tasks.Benchmark do | ||
@moduledoc """ | ||
Run bemchmarks. | ||
""" | ||
|
||
use Mix.Task | ||
|
||
@shortdoc "Run bemchmarks." | ||
|
||
@impl Mix.Task | ||
def run(_), do: Benchmark.run() | ||
end |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
defmodule Benchmark.MixProject do | ||
use Mix.Project | ||
|
||
def project do | ||
[ | ||
app: :benchmark, | ||
deps: deps(), | ||
elixir: "~> 1.10", | ||
start_permanent: Mix.env() == :prod, | ||
version: "0.1.0" | ||
] | ||
end | ||
|
||
def application, do: [extra_applications: [:logger]] | ||
|
||
defp deps do | ||
[ | ||
{:benchee, "~> 1.0"}, | ||
{:fastglobal, "~> 1.0"}, | ||
{:mnemonics, path: ".."} | ||
] | ||
end | ||
end |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
%{ | ||
"benchee": {:hex, :benchee, "1.0.1", "66b211f9bfd84bd97e6d1beaddf8fc2312aaabe192f776e8931cb0c16f53a521", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}], "hexpm", "3ad58ae787e9c7c94dd7ceda3b587ec2c64604563e049b2a0e8baafae832addb"}, | ||
"deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, | ||
"fastglobal": {:hex, :fastglobal, "1.0.0", "f3133a0cda8e9408aac7281ec579c4b4a8386ce0e99ca55f746b9f58192f455b", [:mix], [], "hexpm", "cfdb7ed63910bc75f579cd09e2517618fa9418b56731d51d03f7ba4b400798d0"}, | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
defmodule BenchmarkTest do | ||
use ExUnit.Case | ||
doctest Benchmark | ||
|
||
test "greets the world" do | ||
assert Benchmark.hello() == :world | ||
end | ||
end |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
ExUnit.start() |