# Idea from this: # credo:disable-for-next-line # https://github.com/bencheeorg/benchee/commit/b3ddbc132e641cdf1eec0928b322ced1dab8553f#commitcomment-23381474 elixir_doc = """ Top level module providing convenience access to needed functions as well as the very high level `Benchee.run` API. Intended Elixir interface. """ erlang_doc = """ High-Level interface for more convenient usage from Erlang. Same as `Benchee`. """ for {module, moduledoc} <- [{Benchee, elixir_doc}, {:benchee, erlang_doc}] do defmodule module do @moduledoc moduledoc alias Benchee.Formatter @doc """ Run benchmark jobs defined by a map and optionally provide configuration options. Benchmarks are defined as a map where the keys are a name for the given function and the values are the functions to benchmark. Users can configure the run by passing a keyword list as the second argument. For more information on configuration see `Benchee.Configuration.init/1`. ## Examples Benchee.run( %{ "My Benchmark" => fn -> 1 + 1 end, "My other benchmrk" => fn -> [1] ++ [1] end }, warmup: 2, time: 3 ) """ @spec run(map, keyword) :: Benchee.Suite.t() def run(jobs, config \\ []) when is_list(config) do config |> Benchee.init() |> Benchee.system() |> add_benchmarking_jobs(jobs) |> Benchee.collect() |> Benchee.statistics() |> Benchee.load() |> Benchee.relative_statistics() |> Formatter.output() |> Benchee.profile() end defp add_benchmarking_jobs(suite, jobs) do Enum.reduce(jobs, suite, fn {key, function}, suite_acc -> Benchee.benchmark(suite_acc, key, function) end) end @doc """ A convenience function designed for loading saved benchmarks and running formatters on them. Basically takes the input of the map of jobs away from you and skips unnecessary steps with that data missing (aka not running benchmarks, only running relative statistics). You can use config options as normal, but some options related to benchmarking won't take effect (such as `:time`). The `:load` option however is mandatory to use, as you need to load some benchmarks to report on them. ## Usage Benchee.report(load: ["benchmark-*.benchee"]) """ @spec report(keyword) :: Benchee.Suite.t() def report(config) do if !Access.get(config, :load), do: raise_missing_load() config |> Benchee.init() |> Benchee.system() |> Benchee.load() |> Benchee.relative_statistics() |> Formatter.output() end defp raise_missing_load do raise ArgumentError, "You need to provide at least a :load option for report/1 to make sense" end defdelegate init(), to: Benchee.Configuration defdelegate init(config), to: Benchee.Configuration defdelegate system(suite), to: Benchee.System defdelegate benchmark(suite, name, function), to: Benchee.Benchmark @doc false defdelegate benchmark(suite, name, function, printer), to: Benchee.Benchmark defdelegate collect(suite), to: Benchee.Benchmark @doc false defdelegate collect(suite, printer), to: Benchee.Benchmark defdelegate statistics(suite), to: Benchee.Statistics @doc false defdelegate statistics(suite, printer), to: Benchee.Statistics defdelegate relative_statistics(suite), to: Benchee.RelativeStatistics defdelegate load(suite), to: Benchee.ScenarioLoader defdelegate profile(suite), to: Benchee.Profile end end