-
Notifications
You must be signed in to change notification settings - Fork 1
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
831191d
commit ab24490
Showing
355 changed files
with
48,169 additions
and
0 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# gleamy_bench | ||
|
||
[![Package Version](https://img.shields.io/hexpm/v/gleamy_bench)](https://hex.pm/packages/gleamy_bench) | ||
[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleamy_bench/) | ||
|
||
A library for benchmarking gleam code. | ||
|
||
# How To | ||
|
||
```rust | ||
import gleamy_bench.{Bench, Function, IPS, Input, Min, P, run, table} | ||
|
||
// .. | ||
|
||
Bench( | ||
[ | ||
Input("n=5", 5), | ||
Input("n=10", 10), | ||
Input("n=15", 15), | ||
], | ||
[ | ||
Function("fib1", fib1), | ||
Function("fib2", fib2), | ||
], | ||
) | ||
|> run() | ||
|> table([IPS, Min, P(99)]) | ||
|> io.println() | ||
|
||
``` | ||
|
||
A benchmark is defined by giving a list of inputs and a list of functions to run on those inputs. Each input + function combination will be timed. | ||
|
||
The inputs should all be the same type, and the functions should all accept that type as the only argument. The return type of the function does not matter, only that they all return the same type. | ||
|
||
The `run` function actually runs the benchmark and collects the results. | ||
|
||
The `table` function makes a table out of the results. You can choose the list of statistics you would like to include in the table. | ||
|
||
The output for this example looks like the following. | ||
|
||
``` | ||
Input Function IPS Min P99 | ||
n=5 fib1 2236277.3002 0.0002 0.0006 | ||
n=5 fib2 2493122.7461 0.0002 0.0006 | ||
n=10 fib1 750561.7961 0.0010 0.0022 | ||
n=10 fib2 2755751.7477 0.0002 0.0005 | ||
n=15 fib1 80833.4127 0.0102 0.0184 | ||
n=15 fib2 2139409.1371 0.0003 0.0007 | ||
``` | ||
|
||
## Contributing | ||
|
||
Suggestions and pull requests are welcome! | ||
|
||
## Quick start | ||
|
||
```sh | ||
gleam run # Run the project | ||
gleam test # Run the tests | ||
gleam shell # Run an Erlang shell | ||
``` | ||
|
||
## Installation | ||
|
||
If available on Hex this package can be added to your Gleam project: | ||
|
||
```sh | ||
gleam add gleamy_bench | ||
``` | ||
|
||
and its documentation can be found at <https://hexdocs.pm/gleamy_bench>. |
Empty file.
157 changes: 157 additions & 0 deletions
157
build/dev/erlang/gleam_stdlib/_gleam_artefacts/gleam@@compile.erl
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,157 @@ | ||
#!/usr/bin/env escript | ||
|
||
% TODO: Don't concurrently print warnings and errors | ||
% TODO: Some tests | ||
|
||
-record(arguments, {lib = "./", out = "./", modules = []}). | ||
|
||
main(Args) -> | ||
#arguments{out = Out, lib = Lib, modules = Modules} = parse(Args), | ||
IsElixirModule = fun(Module) -> | ||
filename:extension(Module) =:= ".ex" | ||
end, | ||
{ElixirModules, ErlangModules} = lists:partition(IsElixirModule, Modules), | ||
ok = configure_logging(), | ||
ok = add_lib_to_erlang_path(Lib), | ||
ok = filelib:ensure_dir([Out, $/]), | ||
{ErlangOk, _ErlangBeams} = compile_erlang(ErlangModules, Out), | ||
{ElixirOk, _ElixirBeams} = case ErlangOk of | ||
true -> compile_elixir(ElixirModules, Out); | ||
false -> {false, []} | ||
end, | ||
case ErlangOk and ElixirOk of | ||
true -> ok; | ||
false -> erlang:halt(1) | ||
end. | ||
|
||
compile_erlang(Modules, Out) -> | ||
Workers = start_compiler_workers(Out), | ||
ok = producer_loop(Modules, Workers), | ||
collect_results({true, []}). | ||
|
||
collect_results(Acc = {Result, Beams}) -> | ||
receive | ||
{compiled, Beam} -> collect_results({Result, [Beam | Beams]}); | ||
failed -> collect_results({false, Beams}) | ||
after 0 -> Acc | ||
end. | ||
|
||
producer_loop([], 0) -> | ||
ok; | ||
producer_loop([], Workers) -> | ||
receive | ||
{work_please, _} -> producer_loop([], Workers - 1) | ||
end; | ||
producer_loop([Module | Modules], Workers) -> | ||
receive | ||
{work_please, Worker} -> | ||
erlang:send(Worker, {module, Module}), | ||
producer_loop(Modules, Workers) | ||
end. | ||
|
||
start_compiler_workers(Out) -> | ||
Parent = self(), | ||
NumSchedulers = erlang:system_info(schedulers), | ||
SpawnWorker = fun(_) -> | ||
erlang:spawn_link(fun() -> worker_loop(Parent, Out) end) | ||
end, | ||
lists:foreach(SpawnWorker, lists:seq(1, NumSchedulers)), | ||
NumSchedulers. | ||
|
||
worker_loop(Parent, Out) -> | ||
Options = [report_errors, report_warnings, debug_info, {outdir, Out}], | ||
erlang:send(Parent, {work_please, self()}), | ||
receive | ||
{module, Module} -> | ||
log({compiling, Module}), | ||
case compile:file(Module, Options) of | ||
{ok, ModuleName} -> | ||
Beam = filename:join(Out, ModuleName) ++ ".beam", | ||
Message = {compiled, Beam}, | ||
log(Message), | ||
erlang:send(Parent, Message); | ||
error -> | ||
log({failed, Module}), | ||
erlang:send(Parent, failed) | ||
end, | ||
worker_loop(Parent, Out) | ||
end. | ||
|
||
compile_elixir(Modules, Out) -> | ||
Error = [ | ||
"The program elixir was not found. Is it installed?", | ||
$\n, | ||
"Documentation for installing Elixir can be viewed here:", | ||
$\n, | ||
"https://elixir-lang.org/install.html" | ||
], | ||
case Modules of | ||
[] -> {true, []}; | ||
_ -> | ||
log({starting, "compiler.app"}), | ||
ok = application:start(compiler), | ||
log({starting, "elixir.app"}), | ||
case application:start(elixir) of | ||
ok -> do_compile_elixir(Modules, Out); | ||
_ -> | ||
io:put_chars(standard_error, [Error, $\n]), | ||
{false, []} | ||
end | ||
end. | ||
|
||
do_compile_elixir(Modules, Out) -> | ||
ModuleBins = lists:map(fun(Module) -> | ||
log({compiling, Module}), | ||
list_to_binary(Module) | ||
end, Modules), | ||
OutBin = list_to_binary(Out), | ||
Options = [{dest, OutBin}], | ||
% Silence "redefining module" warnings. | ||
% Compiled modules in the build directory are added to the code path. | ||
% These warnings result from recompiling loaded modules. | ||
% TODO: This line can likely be removed if/when the build directory is cleaned before every compilation. | ||
'Elixir.Code':compiler_options([{ignore_module_conflict, true}]), | ||
case 'Elixir.Kernel.ParallelCompiler':compile_to_path(ModuleBins, OutBin, Options) of | ||
{ok, ModuleAtoms, _} -> | ||
ToBeam = fun(ModuleAtom) -> | ||
Beam = filename:join(Out, atom_to_list(ModuleAtom)) ++ ".beam", | ||
log({compiled, Beam}), | ||
Beam | ||
end, | ||
{true, lists:map(ToBeam, ModuleAtoms)}; | ||
{error, Errors, _} -> | ||
% Log all filenames associated with modules that failed to compile. | ||
% Note: The compiler prints compilation errors upon encountering them. | ||
ErrorFiles = lists:usort([File || {File, _, _} <- Errors]), | ||
Log = fun(File) -> | ||
log({failed, binary_to_list(File)}) | ||
end, | ||
lists:foreach(Log, ErrorFiles), | ||
{false, []}; | ||
_ -> {false, []} | ||
end. | ||
|
||
add_lib_to_erlang_path(Lib) -> | ||
code:add_paths(filelib:wildcard([Lib, "/*/ebin"])). | ||
|
||
parse(Args) -> | ||
parse(Args, #arguments{}). | ||
|
||
parse([], Arguments) -> | ||
Arguments; | ||
parse(["--lib", Lib | Rest], Arguments) -> | ||
parse(Rest, Arguments#arguments{lib = Lib}); | ||
parse(["--out", Out | Rest], Arguments) -> | ||
parse(Rest, Arguments#arguments{out = Out}); | ||
parse([Module | Rest], Arguments = #arguments{modules = Modules}) -> | ||
parse(Rest, Arguments#arguments{modules = [Module | Modules]}). | ||
|
||
configure_logging() -> | ||
Enabled = os:getenv("GLEAM_LOG") /= false, | ||
persistent_term:put(gleam_logging_enabled, Enabled). | ||
|
||
log(Term) -> | ||
case persistent_term:get(gleam_logging_enabled) of | ||
true -> erlang:display(Term), ok; | ||
false -> ok | ||
end. |
Binary file not shown.
Binary file added
BIN
+73 Bytes
build/dev/erlang/gleam_stdlib/_gleam_artefacts/[email protected]_meta
Binary file not shown.
45 changes: 45 additions & 0 deletions
45
build/dev/erlang/gleam_stdlib/_gleam_artefacts/[email protected]
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,45 @@ | ||
-module(gleam@base). | ||
-compile([no_auto_import, nowarn_unused_vars]). | ||
|
||
-export([encode64/2, decode64/1, url_encode64/2, url_decode64/1]). | ||
|
||
-spec encode64(bitstring(), boolean()) -> binary(). | ||
encode64(Input, Padding) -> | ||
Encoded = base64:encode(Input), | ||
case Padding of | ||
true -> | ||
Encoded; | ||
|
||
false -> | ||
gleam@string:replace(Encoded, <<"="/utf8>>, <<""/utf8>>) | ||
end. | ||
|
||
-spec decode64(binary()) -> {ok, bitstring()} | {error, nil}. | ||
decode64(Encoded) -> | ||
Padded = case gleam@bit_string:byte_size( | ||
gleam@bit_string:from_string(Encoded) | ||
) | ||
rem 4 of | ||
0 -> | ||
Encoded; | ||
|
||
N -> | ||
gleam@string:append( | ||
Encoded, | ||
gleam@string:repeat(<<"="/utf8>>, 4 - N) | ||
) | ||
end, | ||
gleam_stdlib:base_decode64(Padded). | ||
|
||
-spec url_encode64(bitstring(), boolean()) -> binary(). | ||
url_encode64(Input, Padding) -> | ||
_pipe = encode64(Input, Padding), | ||
_pipe@1 = gleam@string:replace(_pipe, <<"+"/utf8>>, <<"-"/utf8>>), | ||
gleam@string:replace(_pipe@1, <<"/"/utf8>>, <<"_"/utf8>>). | ||
|
||
-spec url_decode64(binary()) -> {ok, bitstring()} | {error, nil}. | ||
url_decode64(Encoded) -> | ||
_pipe = Encoded, | ||
_pipe@1 = gleam@string:replace(_pipe, <<"-"/utf8>>, <<"+"/utf8>>), | ||
_pipe@2 = gleam@string:replace(_pipe@1, <<"_"/utf8>>, <<"/"/utf8>>), | ||
decode64(_pipe@2). |
Binary file added
BIN
+6.49 KB
build/dev/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache
Binary file not shown.
Binary file added
BIN
+57 Bytes
build/dev/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache_meta
Binary file not shown.
63 changes: 63 additions & 0 deletions
63
build/dev/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.erl
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,63 @@ | ||
-module(gleam@bit_builder). | ||
-compile([no_auto_import, nowarn_unused_vars]). | ||
|
||
-export([append_builder/2, prepend_builder/2, new/0, concat/1, concat_bit_strings/1, from_string/1, prepend_string/2, append_string/2, from_string_builder/1, from_bit_string/1, prepend/2, append/2, to_bit_string/1, byte_size/1]). | ||
-export_type([bit_builder/0]). | ||
|
||
-type bit_builder() :: any(). | ||
|
||
-spec append_builder(bit_builder(), bit_builder()) -> bit_builder(). | ||
append_builder(First, Second) -> | ||
gleam_stdlib:iodata_append(First, Second). | ||
|
||
-spec prepend_builder(bit_builder(), bit_builder()) -> bit_builder(). | ||
prepend_builder(To, Prefix) -> | ||
append_builder(Prefix, To). | ||
|
||
-spec new() -> bit_builder(). | ||
new() -> | ||
gleam_stdlib:identity([]). | ||
|
||
-spec concat(list(bit_builder())) -> bit_builder(). | ||
concat(Builders) -> | ||
gleam_stdlib:identity(Builders). | ||
|
||
-spec concat_bit_strings(list(bitstring())) -> bit_builder(). | ||
concat_bit_strings(Bits) -> | ||
gleam_stdlib:identity(Bits). | ||
|
||
-spec from_string(binary()) -> bit_builder(). | ||
from_string(String) -> | ||
gleam_stdlib:wrap_list(String). | ||
|
||
-spec prepend_string(bit_builder(), binary()) -> bit_builder(). | ||
prepend_string(To, Prefix) -> | ||
append_builder(from_string(Prefix), To). | ||
|
||
-spec append_string(bit_builder(), binary()) -> bit_builder(). | ||
append_string(To, Suffix) -> | ||
append_builder(To, from_string(Suffix)). | ||
|
||
-spec from_string_builder(gleam@string_builder:string_builder()) -> bit_builder(). | ||
from_string_builder(Builder) -> | ||
gleam_stdlib:wrap_list(Builder). | ||
|
||
-spec from_bit_string(bitstring()) -> bit_builder(). | ||
from_bit_string(Bits) -> | ||
gleam_stdlib:wrap_list(Bits). | ||
|
||
-spec prepend(bit_builder(), bitstring()) -> bit_builder(). | ||
prepend(To, Prefix) -> | ||
append_builder(from_bit_string(Prefix), To). | ||
|
||
-spec append(bit_builder(), bitstring()) -> bit_builder(). | ||
append(To, Suffix) -> | ||
append_builder(To, from_bit_string(Suffix)). | ||
|
||
-spec to_bit_string(bit_builder()) -> bitstring(). | ||
to_bit_string(Builder) -> | ||
erlang:list_to_bitstring(Builder). | ||
|
||
-spec byte_size(bit_builder()) -> integer(). | ||
byte_size(Builder) -> | ||
erlang:iolist_size(Builder). |
Binary file added
BIN
+3.81 KB
build/dev/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache
Binary file not shown.
Binary file added
BIN
+29 Bytes
build/dev/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta
Binary file not shown.
56 changes: 56 additions & 0 deletions
56
build/dev/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.erl
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,56 @@ | ||
-module(gleam@bit_string). | ||
-compile([no_auto_import, nowarn_unused_vars]). | ||
|
||
-export([from_string/1, byte_size/1, slice/3, is_utf8/1, to_string/1, concat/1, append/2]). | ||
|
||
-spec from_string(binary()) -> bitstring(). | ||
from_string(X) -> | ||
gleam_stdlib:identity(X). | ||
|
||
-spec byte_size(bitstring()) -> integer(). | ||
byte_size(X) -> | ||
erlang:byte_size(X). | ||
|
||
-spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | | ||
{error, nil}. | ||
slice(String, Position, Length) -> | ||
gleam_stdlib:bit_string_slice(String, Position, Length). | ||
|
||
-spec do_is_utf8(bitstring()) -> boolean(). | ||
do_is_utf8(Bits) -> | ||
case Bits of | ||
<<>> -> | ||
true; | ||
|
||
<<_/utf8, Rest/binary>> -> | ||
do_is_utf8(Rest); | ||
|
||
_ -> | ||
false | ||
end. | ||
|
||
-spec is_utf8(bitstring()) -> boolean(). | ||
is_utf8(Bits) -> | ||
do_is_utf8(Bits). | ||
|
||
-spec do_to_string(bitstring()) -> {ok, binary()} | {error, nil}. | ||
do_to_string(Bits) -> | ||
case is_utf8(Bits) of | ||
true -> | ||
{ok, gleam_stdlib:identity(Bits)}; | ||
|
||
false -> | ||
{error, nil} | ||
end. | ||
|
||
-spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. | ||
to_string(Bits) -> | ||
do_to_string(Bits). | ||
|
||
-spec concat(list(bitstring())) -> bitstring(). | ||
concat(Bit_strings) -> | ||
gleam_stdlib:bit_string_concat(Bit_strings). | ||
|
||
-spec append(bitstring(), bitstring()) -> bitstring(). | ||
append(First, Second) -> | ||
concat([First, Second]). |
Binary file not shown.
Binary file added
BIN
+48 Bytes
build/dev/erlang/gleam_stdlib/_gleam_artefacts/[email protected]_meta
Binary file not shown.
Oops, something went wrong.