Current section
Files
Jump to
Current section
Files
src/internal@bench@bench_utils.erl
-module(internal@bench@bench_utils).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/internal/bench/bench_utils.gleam").
-export([size_to_nodes/1, density_to_probability/1, random_graph/3, grid_graph/2, complete_graph/1, random_dag/2, bipartite_graph/2, format_time/1, graph_stats/1]).
-export_type([graph_size/0, graph_density/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-type graph_size() :: small | medium | large | x_large.
-type graph_density() :: sparse | medium_density | dense.
-file("src/internal/bench/bench_utils.gleam", 19).
-spec size_to_nodes(graph_size()) -> integer().
size_to_nodes(Size) ->
case Size of
small ->
100;
medium ->
1000;
large ->
10000;
x_large ->
100000
end.
-file("src/internal/bench/bench_utils.gleam", 35).
-spec density_to_probability(graph_density()) -> float().
density_to_probability(Density) ->
case Density of
sparse ->
0.01;
medium_density ->
0.05;
dense ->
0.2
end.
-file("src/internal/bench/bench_utils.gleam", 47).
?DOC(" Generate a random graph for benchmarking\n").
-spec random_graph(graph_size(), graph_density(), integer()) -> yog@model:graph(nil, integer()).
random_graph(Size, Density, _) ->
Nodes = size_to_nodes(Size),
Prob = density_to_probability(Density),
yog@generators@random:erdos_renyi_gnp(Nodes, Prob).
-file("src/internal/bench/bench_utils.gleam", 58).
?DOC(" Generate a grid graph (useful for pathfinding benchmarks)\n").
-spec grid_graph(integer(), integer()) -> yog@model:graph(nil, integer()).
grid_graph(Width, Height) ->
Graph = yog:undirected(),
Graph@1 = begin
_pipe = yog@internal@utils:range(0, (Width * Height) - 1),
gleam@list:fold(
_pipe,
Graph,
fun(G, Id) -> yog:add_node(G, Id, nil) end
)
end,
_pipe@1 = yog@internal@utils:range(0, Height - 1),
gleam@list:fold(
_pipe@1,
Graph@1,
fun(G@1, Y) -> _pipe@2 = yog@internal@utils:range(0, Width - 1),
gleam@list:fold(
_pipe@2,
G@1,
fun(Gg, X) ->
Node = (Y * Width) + X,
Gg@1 = case X < (Width - 1) of
true ->
yog:add_edge(Gg, Node, Node + 1, 1);
false ->
Gg
end,
case Y < (Height - 1) of
true ->
yog:add_edge(Gg@1, Node, Node + Width, 1);
false ->
Gg@1
end
end
) end
).
-file("src/internal/bench/bench_utils.gleam", 85).
?DOC(" Generate a complete graph for worst-case testing\n").
-spec complete_graph(integer()) -> yog@model:graph(nil, integer()).
complete_graph(Nodes) ->
yog@generators@classic:complete(Nodes).
-file("src/internal/bench/bench_utils.gleam", 90).
?DOC(" Generate a DAG for topological sort benchmarks\n").
-spec random_dag(integer(), integer()) -> yog@model:graph(nil, integer()).
random_dag(Nodes, Seed) ->
Graph = yog:directed(),
Graph@1 = begin
_pipe = yog@internal@utils:range(0, Nodes - 1),
gleam@list:fold(
_pipe,
Graph,
fun(G, Id) -> yog:add_node(G, Id, nil) end
)
end,
_pipe@1 = yog@internal@utils:range(0, Nodes - 1),
gleam@list:fold(
_pipe@1,
Graph@1,
fun(G@1, From) ->
_pipe@2 = yog@internal@utils:range(From + 1, Nodes - 1),
gleam@list:fold(
_pipe@2,
G@1,
fun(Gg, To) ->
Should_add = ((((From * 31) + (To * 17)) + Seed) rem 10) < 3,
case Should_add of
true ->
yog:add_edge(Gg, From, To, 1);
false ->
Gg
end
end
)
end
).
-file("src/internal/bench/bench_utils.gleam", 114).
?DOC(" Generate a bipartite graph for matching benchmarks\n").
-spec bipartite_graph(integer(), integer()) -> yog@model:graph(nil, integer()).
bipartite_graph(Left_nodes, Right_nodes) ->
yog@generators@classic:complete_bipartite(Left_nodes, Right_nodes).
-file("src/internal/bench/bench_utils.gleam", 127).
-spec float_to_string(float()) -> binary().
float_to_string(F) ->
Rounded = begin
_pipe = F,
_pipe@1 = erlang:round(_pipe),
erlang:integer_to_binary(_pipe@1)
end,
Rounded.
-file("src/internal/bench/bench_utils.gleam", 119).
?DOC(" Format benchmark results for display\n").
-spec format_time(float()) -> binary().
format_time(Microseconds) ->
case {Microseconds < 1000.0, Microseconds < 1000000.0} of
{true, _} ->
<<(float_to_string(Microseconds))/binary, " μs"/utf8>>;
{false, true} ->
<<(float_to_string(Microseconds / 1000.0))/binary, " ms"/utf8>>;
{false, false} ->
<<(float_to_string(Microseconds / 1000000.0))/binary, " s"/utf8>>
end.
-file("src/internal/bench/bench_utils.gleam", 134).
?DOC(" Extract graph statistics for reporting\n").
-spec graph_stats(yog@model:graph(any(), any())) -> {integer(), integer()}.
graph_stats(Graph) ->
Nodes = begin
_pipe = yog:all_nodes(Graph),
erlang:length(_pipe)
end,
Edge_count = case Graph of
{graph, Kind, _, Out_edges, _} ->
_pipe@1 = gleam@dict:fold(
Out_edges,
0,
fun(Count, _, To_edges) -> Count + maps:size(To_edges) end
),
(fun(C) -> case Kind of
undirected ->
C;
directed ->
C
end end)(_pipe@1)
end,
{Nodes, Edge_count}.