Easy and extensible benchmarking in Elixir providing you with lots of statistics!
Helpful assertions for ExUnit
Draw pretty micro benchmarking charts in HTML and allow to export them as png for benchee
Output your Benchee benchmarks as CSV to generate graphs in your favorite spreadsheet tool!
My config and dotfiles
Benche formatter to output json
devonestes/elixir-docker-challenge 2
Can you configure a docker container and local node to establish a connection?!
devonestes/absinthe_tutorial_umbrella 1
A version of the absinthe tutorial as an umbrella app
Example application for testing workshop
push eventelixir-lang/elixir
commit sha 8fca53ad314501e193a4ab21ec2191a0f37600ce
Ensure deprecated macros emit warnings
push time in 3 hours
push eventelixir-lang/elixir
commit sha dac03b17c214689f940864de37c2286bed87d336
Ensure deprecated macros emit warnings
push time in 3 hours
pull request commentelixir-lang/elixir
Fix normalization of partial keyword list elements
:green_heart: :blue_heart: :purple_heart: :yellow_heart: :heart:
comment created time in 5 hours
push eventelixir-lang/elixir
commit sha fb7179ff713c7fc9444307eb563c289a03505c1c
Fix normalization of partial keyword list elements (#11084)
push time in 5 hours
PR merged elixir-lang/elixir
The Elixir.Normalizer lets us feed any arbitrary AST to the formatter, but if the user provides a list, and an element is a 2-tuple that is not one of the last elements, and the first element is a wrapped atom with format: :keyword metadata, then the formatter will happily print it as a keyword list element, despite it being invalid syntax, for example:
iex> opts = [literal_encoder: &{:ok, {:__block__, &2, [&1]}}]
iex> {_, _, [[tuple]]} = Code.string_to_quoted("[a: b]", opts)
iex> Macro.to_string([tuple, :not_a_tuple, tuple])
"[a: b, :not_a_tuple, a: b]"
With this PR we would get the expected output:
iex> Macro.to_string([tuple, :not_a_tuple, tuple])
"[{:a, b}, :not_a_tuple, a: b]"
pr closed time in 5 hours
PR opened elixir-lang/elixir
The Elixir.Normalizer lets us feed any arbitrary AST to the formatter, but if the user provides a list, and an element is a 2-tuple that is not one of the last elements, and the first element is a wrapped atom with format: :keyword metadata, then the formatter will happily print it as a keyword list element, despite it being invalid syntax, for example:
iex> opts = [literal_encoder: &{:ok, {:__block__, &2, [&1]}}]
iex> {_, _, [[tuple]]} = Code.string_to_quoted("[a: b]", opts)
iex> Macro.to_string([tuple, :not_a_tuple, tuple])
"[a: b, :not_a_tuple, a: b]"
With this PR we would get the expected output:
iex> Macro.to_string([tuple, :not_a_tuple, tuple])
"[{:a, b}, :not_a_tuple, a: b]"
pr created time in 5 hours
push eventelixir-lang/elixir
commit sha 2a4312412be39303af08ccd0cef81b5bbcd55eac
Optimize Enum.zip/2 (#11083)
push time in 14 hours
pull request commentelixir-lang/elixir
:green_heart: :blue_heart: :purple_heart: :yellow_heart: :heart:
comment created time in 14 hours
PR merged elixir-lang/elixir
Hi! I noticed that the generic implementation of Enum.zip/2 relying on zip_with with an anonymous function was significantly slower on lists than having dedicated private functions.
Some quick benchmarks suggest a speedup of 2.5~3x compared to the current implementation:
https://github.com/sabiwara/elixir_benches/blob/main/bench/fast_enum_zip.results.txt
Note: I went with a tail-recursive implementation, but I benchmarked a body-recursive version as well and it seems noticeably slower (due to the JIT?) so I kept the former.
pr closed time in 14 hours
PR opened elixir-lang/elixir
Hi! I noticed that the generic implementation of Enum.zip/2 relying on zip_with with an anonymous function was significantly slower on lists than having dedicated private functions.
Some quick benchmarks suggest a speedup of 2.5~3x compared to the current implementation:
https://github.com/sabiwara/elixir_benches/blob/main/bench/fast_enum_zip.results.txt
Note: I went with a tail-recursive implementation, but I benchmarked a body-recursive version as well and it seems noticeably slower (due to the JIT?) so I kept the former.
pr created time in a day
push eventelixir-lang/elixir
commit sha 76dfedb2e39f9bdfce68cd2bdca36c41370e5e31
Compile most recently changed files first
push time in a day
push eventelixir-lang/elixir
commit sha d9028a8d0405d19076418376ab50bdc83ff72974
Compile most recently changed files first
push time in a day
starteddevonestes/fast-elixir
started time in a day
pull request commentelixir-lang/elixir
Add `--cerl` flag to `elixir` shell script.
Btw, note that you can currently do this:
ELIXIR_CLI_DRY_RUN=1 elixir -e "IO.puts :ok"
And that will print the whole command we run. You can then modify it to use cerl. Could this be enough? It definitely gives more flexibility.
comment created time in a day
Pull request review commentelixir-lang/elixir
Add `--cerl` flag to `elixir` shell script.
if [ -n "$RUN_ERL_PIPE" ]; then mkdir -p "$RUN_ERL_PIPE" mkdir -p "$RUN_ERL_LOG" ERL_EXEC="run_erl"- set -- "$ERTS_BIN$ERL_EXEC" -daemon "$RUN_ERL_PIPE/" "$RUN_ERL_LOG/" "$ESCAPED"+ set -- "$ERTS_BIN$ERL_EXEC" $CERL_ARGS -daemon "$RUN_ERL_PIPE/" "$RUN_ERL_LOG/" "$ESCAPED"
Not sure if this makes a difference here because we are setting ERL_EXEC="run_erl" just above.
comment created time in a day
Pull request review commentelixir-lang/elixir
Add `--cerl` flag to `elixir` shell script.
while [ $I -le $LENGTH ]; do --werl) if [ "$OS" = "Windows_NT" ]; then ERL_EXEC="werl"; fi ;;+ --cerl)+ if ! [ -x "$(command -v cerl)" ]; then+ echo 'Error: cerl not found in path.' >&2+ exit 1+ fi+ S=2+ ERL_EXEC="$(which cerl)"
Can this be cerl instead?
ERL_EXEC="cerl"
comment created time in a day
pull request commentelixir-lang/elixir
Add `--cerl` flag to `elixir` shell script.
This would be a dramatic ergonomic improvement from before, the way I usually did it was to hack changes into the elixir script manually.
comment created time in a day
PR opened elixir-lang/elixir
The primary use case for this is making it easier to debug NIFs.
A new --cerl argument is added to elixir.
This will run elixir by the cerl command, which contains a variety of utilities for debugging, including:
--cerl "-lldb"- will run the erts within lldb, for debugging hard crashes--cerl "-valgrind"- will run the erts within valgrid, useful for finding memory issues- all other flags documented within the
cerlscript from OTP
I am not a shell script expert, so I would very much appreciate comments on anything that could be done better.
pr created time in a day
push eventelixir-lang/elixir
commit sha e5fa840b1cf9888e8a5bc53fe3bf6ba270033144
Allow :eof on IO.getn (#11081)
push time in a day
pull request commentelixir-lang/elixir
:green_heart: :blue_heart: :purple_heart: :yellow_heart: :heart:
comment created time in a day
pull request commentelixir-lang/elixir
Rely on modification time and hash to determine modified sources
There is absolutely no rush. I plan to do a new Elixir patch release this week with the faster app loading and so it would be too soon to include this (I typically like to run with those changes for a couple weeks).
comment created time in 2 days
pull request commentelixir-lang/elixir
Rely on modification time and hash to determine modified sources
I'll work on that tomorrow...
comment created time in 2 days
pull request commentelixir-lang/elixir
Rely on modification time and hash to determine modified sources
And yes, clearly, the hashes have to be written to the manifest...
comment created time in 2 days
Pull request review commentelixir-lang/elixir
Rely on modification time and hash to determine modified sources
defmodule Mix.Compilers.Elixir do dest ) - {modules, exports, changed, sources_stats}+ {modules, exports, changed, sources_snapshots} end - defp mtimes_and_sizes(sources) do+ defp snapshots(sources) do Enum.reduce(sources, %{}, fn source(source: source, external: external), map -> Enum.reduce([source | external], map, fn file, map ->- Map.put_new_lazy(map, file, fn -> Mix.Utils.last_modified_and_size(file) end)+ Map.put_new_lazy(map, file, fn -> snapshot(file) end) end) end) end + defp digest(file) do+ case File.read(file) do+ {:ok, content} ->+ :crypto.hash(:md5, content)
:erlang.md5(content)
The difference is that :crypto is a separate application, that we would need to start and depend on, but luckily MD5 is part of Erlang too.
comment created time in 2 days
pull request commentelixir-lang/elixir
Rely on modification time and hash to determine modified sources
Great, thanks for these pointers 👍
comment created time in 2 days
pull request commentelixir-lang/elixir
Rely on modification time and hash to determine modified sources
Btw, a future step would be to keep the size and digests for those external files too, such as phoenix templates, but it can be a separate PR!
comment created time in 2 days