Skip to content

Commit

Permalink
Make the function finding best units available for plugins
Browse files Browse the repository at this point in the history
benchee_html wants this :)
  • Loading branch information
PragTob committed Oct 15, 2017
1 parent c697596 commit 455a237
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 19 deletions.
53 changes: 53 additions & 0 deletions lib/benchee/conversion.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
defmodule Benchee.Conversion do
@moduledoc """
Integration of the conversion of multiple units with benchee.
Can be used by plugins to use benche unit scaling logic.
"""

alias Benchee.Conversion.{Duration, Count}

@doc """
Takes scenarios and a given scaling_strategy, returns the best unit for
run_time and ips, according to the scaling_strategy, in a map.
The units can then be passed on to the appropriate `format` calls to format
the output of arbitrary values with the right unit.
## Examples
iex> statistics = %Benchee.Statistics{average: 1000.0, ips: 1000.0}
iex> scenario = %Benchee.Benchmark.Scenario{run_time_statistics: statistics}
iex> Benchee.Conversion.run_time_units([scenario], :best)
%{
ips: %Benchee.Conversion.Unit{
label: "K",
long: "Thousand",
magnitude: 1000,
name: :thousand
},
run_time: %Benchee.Conversion.Unit{
label: "ms",
long: "Milliseconds",
magnitude: 1000,
name: :millisecond
}
}
"""
def run_time_units(scenarios, scaling_strategy) do
# Produces a map like
# %{run_time: [12345, 15431, 13222], ips: [1, 2, 3]}
measurements =
scenarios
|> Enum.flat_map(fn(scenario) ->
Map.to_list(scenario.run_time_statistics)
end)
|> Enum.group_by(fn({stat_name, _}) -> stat_name end,
fn({_, value}) -> value end)

%{
run_time: Duration.best(measurements.average, strategy: scaling_strategy),
ips: Count.best(measurements.ips, strategy: scaling_strategy),
}
end
end
24 changes: 5 additions & 19 deletions lib/benchee/formatters/console.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ defmodule Benchee.Formatters.Console do

@behaviour Benchee.Formatter

alias Benchee.{Statistics, Suite, Benchmark.Scenario, Configuration}
alias Benchee.{
Statistics, Suite, Benchmark.Scenario, Configuration, Conversion
}
alias Benchee.Conversion.{Count, Duration, Unit, DeviationPercent}

@type unit_per_statistic :: %{atom => Unit.t}
Expand Down Expand Up @@ -139,7 +141,8 @@ defmodule Benchee.Formatters.Console do
@spec format_scenarios([Scenario.t], map) :: [any, ...]
def format_scenarios(scenarios, config) do
sorted_scenarios = Statistics.sort(scenarios)
units = units(sorted_scenarios, config)
%{unit_scaling: scaling_strategy} = config
units = Conversion.run_time_units(sorted_scenarios, scaling_strategy)
label_width = label_width(sorted_scenarios)

[column_descriptors(label_width) |
Expand Down Expand Up @@ -170,23 +173,6 @@ defmodule Benchee.Formatters.Console do
fn(scenario) -> format_scenario(scenario, units, label_width) end)
end

defp units(scenarios, %{unit_scaling: scaling_strategy}) do
# Produces a map like
# %{run_time: [12345, 15431, 13222], ips: [1, 2, 3]}
measurements =
scenarios
|> Enum.flat_map(fn(scenario) ->
Map.to_list(scenario.run_time_statistics)
end)
|> Enum.group_by(fn({stat_name, _}) -> stat_name end,
fn({_, value}) -> value end)

%{
run_time: Duration.best(measurements.average, strategy: scaling_strategy),
ips: Count.best(measurements.ips, strategy: scaling_strategy),
}
end

@spec format_scenario(Scenario.t, unit_per_statistic, integer) :: String.t
defp format_scenario(%Scenario{
job_name: name,
Expand Down
4 changes: 4 additions & 0 deletions test/benchee/conversion_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
defmodule Benchee.ConversionTest do
use ExUnit.Case
doctest Benchee.Conversion
end

0 comments on commit 455a237

Please sign in to comment.