Packages

A robust, type-safe slugification library for Gleam that converts text into URL-friendly slugs

Current section

Files

Jump to
glugify src glugify@performance.erl
Raw

src/glugify@performance.erl

-module(glugify@performance).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-define(FILEPATH, "src/glugify/performance.gleam").
-export([print_benchmark_result/1, new_string_builder/0, append_to_builder/2, builder_to_string/1, benchmark_slugify/2, benchmark_slugify_with_config/3, run_performance_suite/0, print_performance_report/0]).
-export_type([benchmark_result/0, optimized_string_builder/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 benchmark_result() :: {benchmark_result,
binary(),
integer(),
integer(),
integer(),
integer()}.
-type optimized_string_builder() :: {optimized_string_builder,
gleam@string_tree:string_tree()}.
-file("src/glugify/performance.gleam", 56).
-spec benchmark_slugify_loop(binary(), integer(), integer()) -> nil.
benchmark_slugify_loop(Input, Remaining, _) ->
case Remaining of
0 ->
nil;
_ ->
_ = glugify:slugify(Input),
benchmark_slugify_loop(Input, Remaining - 1, 0)
end.
-file("src/glugify/performance.gleam", 104).
-spec benchmark_slugify_with_config_loop(
binary(),
glugify@config:config(),
integer(),
integer()
) -> nil.
benchmark_slugify_with_config_loop(Input, Config, Remaining, _) ->
case Remaining of
0 ->
nil;
_ ->
_ = glugify:slugify_with(Input, Config),
benchmark_slugify_with_config_loop(Input, Config, Remaining - 1, 0)
end.
-file("src/glugify/performance.gleam", 161).
?DOC(
" Prints a formatted benchmark result to the console.\n"
" \n"
" Outputs operation count, total time, operations per second,\n"
" and average time per operation in a readable format.\n"
).
-spec print_benchmark_result(benchmark_result()) -> nil.
print_benchmark_result(Result) ->
gleam_stdlib:println(
<<<<<<<<<<<<<<<<<<<<<<"Benchmark: "/utf8,
(erlang:element(2, Result))/binary>>/binary,
" | Operations: "/utf8>>/binary,
(erlang:integer_to_binary(
erlang:element(3, Result)
))/binary>>/binary,
" | Total Time: "/utf8>>/binary,
(erlang:integer_to_binary(
erlang:element(4, Result)
))/binary>>/binary,
"ms"/utf8>>/binary,
" | Ops/sec: "/utf8>>/binary,
(erlang:integer_to_binary(erlang:element(5, Result)))/binary>>/binary,
" | Avg: "/utf8>>/binary,
(erlang:integer_to_binary(erlang:element(6, Result)))/binary>>/binary,
"μs"/utf8>>
).
-file("src/glugify/performance.gleam", 226).
?DOC(
" Creates a new empty string builder.\n"
" \n"
" ## Examples\n"
" \n"
" ```gleam\n"
" let builder = new_string_builder()\n"
" ```\n"
).
-spec new_string_builder() -> optimized_string_builder().
new_string_builder() ->
{optimized_string_builder, gleam@string_tree:new()}.
-file("src/glugify/performance.gleam", 243).
?DOC(
" Appends text to the string builder.\n"
" \n"
" This operation is efficient and doesn't require copying the entire\n"
" string like regular string concatenation would.\n"
" \n"
" ## Examples\n"
" \n"
" ```gleam\n"
" new_string_builder()\n"
" |> append_to_builder(\"hello\")\n"
" |> append_to_builder(\" \")\n"
" |> append_to_builder(\"world\")\n"
" ```\n"
).
-spec append_to_builder(optimized_string_builder(), binary()) -> optimized_string_builder().
append_to_builder(Builder, Text) ->
{optimized_string_builder,
gleam@string_tree:append(erlang:element(2, Builder), Text)}.
-file("src/glugify/performance.gleam", 264).
?DOC(
" Converts the string builder to a final string.\n"
" \n"
" This operation finalizes the string building process and returns\n"
" the concatenated result as a regular string.\n"
" \n"
" ## Examples\n"
" \n"
" ```gleam\n"
" new_string_builder()\n"
" |> append_to_builder(\"hello\")\n"
" |> append_to_builder(\" world\")\n"
" |> builder_to_string()\n"
" // -> \"hello world\"\n"
" ```\n"
).
-spec builder_to_string(optimized_string_builder()) -> binary().
builder_to_string(Builder) ->
unicode:characters_to_binary(erlang:element(2, Builder)).
-file("src/glugify/performance.gleam", 33).
?DOC(
" Benchmarks the simple `slugify` function with a given input.\n"
" \n"
" Runs the slugification operation for the specified number of iterations\n"
" and measures the total time, average time per operation, and operations per second.\n"
" \n"
" ## Examples\n"
" \n"
" ```gleam\n"
" let result = benchmark_slugify(\"Hello World\", 1000)\n"
" // Measures performance of 1000 slugify operations\n"
" ```\n"
).
-spec benchmark_slugify(binary(), integer()) -> benchmark_result().
benchmark_slugify(Input, Iterations) ->
Start_time = erlang:system_time(),
benchmark_slugify_loop(Input, Iterations, 0),
End_time = erlang:system_time(),
Total_time_microseconds = End_time - Start_time,
Total_time_ms = Total_time_microseconds div 1000,
Avg_time_per_op = case Iterations of
0 -> 0;
Gleam@denominator -> Total_time_microseconds div Gleam@denominator
end,
Ops_per_second = case Total_time_ms of
0 ->
Iterations * 1000;
_ ->
case Total_time_ms of
0 -> 0;
Gleam@denominator@1 -> (Iterations * 1000) div Gleam@denominator@1
end
end,
{benchmark_result,
<<"slugify"/utf8>>,
Iterations,
Total_time_ms,
Ops_per_second,
Avg_time_per_op}.
-file("src/glugify/performance.gleam", 77).
?DOC(
" Benchmarks the `slugify_with` function with custom configuration.\n"
" \n"
" Runs the slugification operation with the provided configuration\n"
" for the specified number of iterations and measures performance.\n"
" \n"
" ## Examples\n"
" \n"
" ```gleam\n"
" let custom_config = config.default() |> config.with_separator(\"_\")\n"
" let result = benchmark_slugify_with_config(\"Hello World\", custom_config, 1000)\n"
" ```\n"
).
-spec benchmark_slugify_with_config(
binary(),
glugify@config:config(),
integer()
) -> benchmark_result().
benchmark_slugify_with_config(Input, Config, Iterations) ->
Start_time = erlang:system_time(),
benchmark_slugify_with_config_loop(Input, Config, Iterations, 0),
End_time = erlang:system_time(),
Total_time_microseconds = End_time - Start_time,
Total_time_ms = Total_time_microseconds div 1000,
Avg_time_per_op = case Iterations of
0 -> 0;
Gleam@denominator -> Total_time_microseconds div Gleam@denominator
end,
Ops_per_second = case Total_time_ms of
0 ->
Iterations * 1000;
_ ->
case Total_time_ms of
0 -> 0;
Gleam@denominator@1 -> (Iterations * 1000) div Gleam@denominator@1
end
end,
{benchmark_result,
<<"slugify_with_config"/utf8>>,
Iterations,
Total_time_ms,
Ops_per_second,
Avg_time_per_op}.
-file("src/glugify/performance.gleam", 129).
?DOC(
" Runs a comprehensive performance benchmark suite.\n"
" \n"
" Tests various input types and configurations:\n"
" - Simple text\n"
" - Unicode text with emojis\n"
" - Long text (200+ characters)\n"
" - Complex text with mixed case and symbols\n"
" - Both default and custom configurations\n"
" \n"
" Returns a list of benchmark results for analysis.\n"
).
-spec run_performance_suite() -> list(benchmark_result()).
run_performance_suite() ->
Simple_text = <<"Hello World"/utf8>>,
Unicode_text = <<"Héllo Wörld with émojis 🎉"/utf8>>,
Long_text = <<"This is a very long text that needs to be processed and slugified to test performance with longer strings that might be more representative of real world usage patterns"/utf8>>,
Complex_text = <<"A Mix of UPPER & lower case, with spéciàl chãractërs, numbers 123, and symbols @#$%^&*()"/utf8>>,
Custom_config = begin
_pipe = glugify@config:default(),
_pipe@1 = glugify@config:with_separator(_pipe, <<"_"/utf8>>),
_pipe@2 = glugify@config:with_max_length(_pipe@1, 20),
glugify@config:with_word_boundary(_pipe@2, true)
end,
Iterations = 100,
[benchmark_slugify(Simple_text, Iterations),
benchmark_slugify(Unicode_text, Iterations),
benchmark_slugify(Long_text, Iterations),
benchmark_slugify(Complex_text, Iterations),
benchmark_slugify_with_config(Simple_text, Custom_config, Iterations),
benchmark_slugify_with_config(Unicode_text, Custom_config, Iterations),
benchmark_slugify_with_config(Long_text, Custom_config, Iterations),
benchmark_slugify_with_config(Complex_text, Custom_config, Iterations)].
-file("src/glugify/performance.gleam", 185).
?DOC(
" Runs the complete performance suite and prints a formatted report.\n"
" \n"
" This function executes all benchmarks and displays:\n"
" - Individual benchmark results\n"
" - Summary statistics\n"
" - Total operations executed\n"
" - Average operations per second across all tests\n"
).
-spec print_performance_report() -> nil.
print_performance_report() ->
gleam_stdlib:println(
<<"=== Glugify Performance Benchmark Report ==="/utf8>>
),
gleam_stdlib:println(<<""/utf8>>),
Results = run_performance_suite(),
gleam@list:each(Results, fun print_benchmark_result/1),
gleam_stdlib:println(<<""/utf8>>),
gleam_stdlib:println(<<"=== Performance Summary ==="/utf8>>),
Total_ops = gleam@list:fold(
Results,
0,
fun(Acc, Result) -> Acc + erlang:element(3, Result) end
),
Avg_ops_per_second = case erlang:length(Results) of
0 ->
0;
Len ->
Total_ops_per_second = gleam@list:fold(
Results,
0,
fun(Acc@1, Result@1) -> Acc@1 + erlang:element(5, Result@1) end
),
case Len of
0 -> 0;
Gleam@denominator -> Total_ops_per_second div Gleam@denominator
end
end,
gleam_stdlib:println(
<<"Total operations executed: "/utf8,
(erlang:integer_to_binary(Total_ops))/binary>>
),
gleam_stdlib:println(
<<"Average operations per second: "/utf8,
(erlang:integer_to_binary(Avg_ops_per_second))/binary>>
).