Skip to content

Commit

Permalink
Avoid __using__ for erlang interface, simpler iteration and def
Browse files Browse the repository at this point in the history
  • Loading branch information
PragTob committed Aug 1, 2017
1 parent f6b1145 commit 24eca1c
Showing 1 changed file with 72 additions and 79 deletions.
151 changes: 72 additions & 79 deletions lib/benchee.ex
Original file line number Diff line number Diff line change
@@ -1,92 +1,85 @@
# Idea from this:
# credo:disable-for-next-line
# https://elixirforum.com/t/writing-a-library-for-use-in-both-elixir-and-erlang/2900/5?u=pragtob
defmodule Benchee.Impl do
@moduledoc false
defmacro __using__(_) do
quote do
@doc """
Run benchmark jobs defined by a map and optionally provide configuration
options.
Runs the given benchmarks and prints the results on the console.
* jobs - a map from descriptive benchmark job name to a function to be
executed and benchmarked
* configuration - configuration options to alter what Benchee does, see
`Benchee.Configuration.init/1` for documentation of the available options.
## Examples
Benchee.run(%{"My Benchmark" => fn -> 1 + 1 end,
"My other benchmrk" => fn -> "1" ++ "1" end}, time: 3)
# Prints a summary of the benchmark to the console
"""
def run(jobs, config \\ [])
def run(jobs, config) when is_list(config) do
do_run(jobs, config)
end
def run(config, jobs) when is_map(jobs) do
# pre 0.6.0 way of passing in the config first and as a map
do_run(jobs, config)
end
# https://github.com/PragTob/benchee/commit/b3ddbc132e641cdf1eec0928b322ced1dab8553f#commitcomment-23381474

defp do_run(jobs, config) do
jobs
|> run_benchmarks(config)
|> output_results
end
elixir_doc = """
Top level module providing convenience access to needed functions as well
as the very high level `Benchee.run` API.
defp run_benchmarks(jobs, config) do
config
|> Benchee.init
|> Benchee.system
|> add_benchmarking_jobs(jobs)
|> Benchee.measure
|> Benchee.statistics
end
Intended Elixir interface.
"""

defp output_results(suite = %{configuration: %{formatters: formatters}}) do
Enum.each formatters, fn(output_function) ->
output_function.(suite)
end
erlang_doc = """
High-Level interface for more convenient usage from Erlang. Same as `Benchee`.
"""

suite
end
for {module, moduledoc} <- [{Benchee, elixir_doc}, {:benchee, erlang_doc}] do
defmodule module do
@moduledoc moduledoc

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 """
Run benchmark jobs defined by a map and optionally provide configuration
options.
defdelegate init(), to: Benchee.Configuration
defdelegate init(config), to: Benchee.Configuration
defdelegate system(suite), to: Benchee.System
defdelegate measure(suite), to: Benchee.Benchmark
defdelegate measure(suite, printer), to: Benchee.Benchmark
defdelegate benchmark(suite, name, function), to: Benchee.Benchmark
defdelegate statistics(suite), to: Benchee.Statistics
defdelegate benchmark(suite, name, function, printer),
to: Benchee.Benchmark
Runs the given benchmarks and prints the results on the console.
* jobs - a map from descriptive benchmark job name to a function to be
executed and benchmarked
* configuration - configuration options to alter what Benchee does, see
`Benchee.Configuration.init/1` for documentation of the available options.
## Examples
Benchee.run(%{"My Benchmark" => fn -> 1 + 1 end,
"My other benchmrk" => fn -> "1" ++ "1" end}, time: 3)
# Prints a summary of the benchmark to the console
"""
def run(jobs, config \\ [])
def run(jobs, config) when is_list(config) do
do_run(jobs, config)
end
def run(config, jobs) when is_map(jobs) do
# pre 0.6.0 way of passing in the config first and as a map
do_run(jobs, config)
end
end
end

defmodule Benchee do
@moduledoc """
Top level module providing convenience access to needed functions as well
as the very high level `Benchee.run` API.
defp do_run(jobs, config) do
jobs
|> run_benchmarks(config)
|> output_results
end

Intended Elixir interface.
"""
use Benchee.Impl
end
defp run_benchmarks(jobs, config) do
config
|> Benchee.init
|> Benchee.system
|> add_benchmarking_jobs(jobs)
|> Benchee.measure
|> Benchee.statistics
end

defp output_results(suite = %{configuration: %{formatters: formatters}}) do
Enum.each formatters, fn(output_function) ->
output_function.(suite)
end

defmodule :benchee do
@moduledoc """
High-Level interface for more convenient usage from Erlang. Same as `Benchee`.
"""
use Benchee.Impl
suite
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

defdelegate init(), to: Benchee.Configuration
defdelegate init(config), to: Benchee.Configuration
defdelegate system(suite), to: Benchee.System
defdelegate measure(suite), to: Benchee.Benchmark
defdelegate measure(suite, printer), to: Benchee.Benchmark
defdelegate benchmark(suite, name, function), to: Benchee.Benchmark
defdelegate statistics(suite), to: Benchee.Statistics
defdelegate benchmark(suite, name, function, printer), to: Benchee.Benchmark
end
end

0 comments on commit 24eca1c

Please sign in to comment.