diff --git a/README.md b/README.md index 8fa951e..e9cc5fe 100644 --- a/README.md +++ b/README.md @@ -496,7 +496,7 @@ mix aoc.run [options] * `-y, --year ` - Year of the puzzle. Defaults to today's year or custom default. * `-d, --day ` - Day of the puzzle. Defaults to today's day or custom default. * `-p, --part ` - Part of the puzzle. Defaults to both parts. -* `-b, --benchmark` - Runs the solution repeatedly for 5 seconds to print statistics about execution time. Defaults to `false`. +* `-b, --benchmark` - Runs the solution parts repeatedly for 5 seconds to print statistics about execution time. Defaults to `false`. * `--help` - Displays this help. diff --git a/lib/aoc.ex b/lib/aoc.ex index 4d7bbf6..0b72909 100644 --- a/lib/aoc.ex +++ b/lib/aoc.ex @@ -15,7 +15,7 @@ defmodule AoC do end end - defp find_module(year, day) do + def find_module(year, day) do with {:error, _} <- Code.ensure_loaded(Mod.module_name(year, day)), {:error, _} <- Code.ensure_loaded(Mod.legacy_module_name(year, day)) do {:error, :not_implemented} @@ -27,7 +27,7 @@ defmodule AoC do defp do_run(year, day, module, part) when is_atom(module) and part in [:part_one, :part_two] do with {:ok, input_path} <- Input.ensure_local(year, day), :ok <- ensure_part(module, part) do - {:ok, do_run_part(module, part, input_path)} + {:ok, call_part(module, part, input_path)} else {:error, :nofile} -> {:error, :not_implemented} {:error, _} = err -> err @@ -42,7 +42,7 @@ defmodule AoC do end end - defp do_run_part(module, part, input_path) do + defp call_part(module, part, input_path) do problem = generate_problem(module, part, input_path) apply(module, part, [problem]) end diff --git a/lib/aoc/compute_cache.ex b/lib/aoc/compute_cache.ex index 7efc558..c95a63c 100644 --- a/lib/aoc/compute_cache.ex +++ b/lib/aoc/compute_cache.ex @@ -1,4 +1,5 @@ defmodule AoC.ComputeCache do + @moduledoc false defmacro __using__(opts) do quote bind_quoted: binding() do cache_vsn = Keyword.get(opts, :version, 0) diff --git a/lib/mix/tasks/aoc.run.ex b/lib/mix/tasks/aoc.run.ex index e31bb48..31e276b 100644 --- a/lib/mix/tasks/aoc.run.ex +++ b/lib/mix/tasks/aoc.run.ex @@ -11,7 +11,7 @@ defmodule Mix.Tasks.Aoc.Run do default: false, short: :b, doc: - "Runs the solution repeatedly for 5 seconds to print statistics about execution time." + "Runs the solution parts repeatedly for 5 seconds to print statistics about execution time." ] ) @@ -40,30 +40,41 @@ defmodule Mix.Tasks.Aoc.Run do CLI.color(:yellow, to_string(day)) ]) - part = translate_part(part) - run_print(year, day, part) + benchmarkable_parts = + part + |> expand_parts() + |> Stream.map(fn part -> {part, run_part(year, day, part)} end) + |> Stream.map(fn {part, {usecs, result}} -> + print_result(result, usecs, year, day, part) + {part, result} + end) + |> Stream.filter(fn {_part, result} -> match?({:ok, _}, result) end) + |> Enum.map(fn {part, _} -> part end) if options.benchmark do - benchmark(year, day, [part]) + benchmark(year, day, benchmarkable_parts) end end - defp translate_part(n) do + defp expand_parts(n) do case n do - 1 -> :part_one - 2 -> :part_two - nil -> nil + 1 -> [:part_one] + 2 -> [:part_two] + nil -> [:part_one, :part_two] end end - defp run_print(year, day, nil) do - run_print(year, day, :part_one) - run_print(year, day, :part_two) + defp run_part(year, day, part) do + {_usecs, _result} = spawn_run(year, day, part) end - defp run_print(year, day, part) do - {usecs, result} = :timer.tc(fn -> run(year, day, part) end) - print_result(result, usecs, year, day, part) + defp spawn_run(year, day, part) do + task = + Task.async(fn -> + {_usecs, _result} = :timer.tc(fn -> run(year, day, part) end) + end) + + Task.await(task, :infinity) end defp run(year, day, part) do @@ -108,12 +119,7 @@ defmodule Mix.Tasks.Aoc.Run do Exception.format_banner(kind, e, stack) end - defp benchmark(year, day, [nil]) do - benchmark(year, day, [:part_one, :part_two]) - end - defp benchmark(year, day, parts) do - parts = Enum.filter(parts, &match?({:ok, _}, run(year, day, &1))) benchables = Enum.map(parts, fn part -> {part, fn -> AoC.run(year, day, part) end} end) case benchables do