Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce BenchmarkConfig to selectively use config in benchmark #414

Merged
merged 2 commits into from
Dec 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions lib/benchee/benchmark.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule Benchee.Benchmark do
Exposes `benchmark/4` and `collect/3` functions.
"""

alias Benchee.Benchmark.{Runner, ScenarioContext}
alias Benchee.Benchmark.{BenchmarkConfig, Runner, ScenarioContext}
alias Benchee.Output.BenchmarkPrinter, as: Printer
alias Benchee.Scenario
alias Benchee.Suite
Expand Down Expand Up @@ -118,7 +118,14 @@ defmodule Benchee.Benchmark do
runner \\ Runner
) do
printer.configuration_information(suite)
scenario_context = %ScenarioContext{config: config, printer: printer, system: system}
benchmark_config = BenchmarkConfig.from(config)

scenario_context = %ScenarioContext{
config: benchmark_config,
printer: printer,
system: system
}

scenarios = runner.run_scenarios(scenarios, scenario_context)
%Suite{suite | scenarios: scenarios}
end
Expand Down
53 changes: 53 additions & 0 deletions lib/benchee/benchmark/benchmark_config.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
defmodule Benchee.Benchmark.BenchmarkConfig do
@moduledoc """
Benchmark Configuration, practically a sub set of `Benchee.Configuration`

`Benchee.Configuration` holds too much data that we don't want to send into the benchmarking
processes - inputs being potentially huge. Hence, we take the sub set the benchmarks need and
put it in here. Since this is a benchmarking library, to no one's surprise these are a lot of
them.
See: https://github.com/bencheeorg/benchee/issues/412
"""

alias Benchee.Benchmark.Hooks

@keys [
:warmup,
:time,
:memory_time,
:reduction_time,
:pre_check,
:measure_function_call_overhead,
:before_each,
:after_each,
:before_scenario,
:after_scenario,
:parallel,
:print
]

defstruct @keys

@type t :: %__MODULE__{
time: number,
warmup: number,
memory_time: number,
reduction_time: number,
pre_check: boolean,
measure_function_call_overhead: boolean,
print: map,
before_each: Hooks.hook_function() | nil,
after_each: Hooks.hook_function() | nil,
before_scenario: Hooks.hook_function() | nil,
after_scenario: Hooks.hook_function() | nil,
measure_function_call_overhead: boolean,
parallel: pos_integer()
}

alias Benchee.Configuration

def from(config = %Configuration{}) do
values = Map.take(config, @keys)
struct!(__MODULE__, values)
end
end
10 changes: 5 additions & 5 deletions lib/benchee/benchmark/runner.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ defmodule Benchee.Benchmark.Runner do
# This module actually runs our benchmark scenarios, adding information about
# run time and memory usage to each scenario.

alias Benchee.{Benchmark, Configuration, Scenario, Utility.Parallel}
alias Benchee.{Benchmark, Scenario, Utility.Parallel}

alias Benchmark.{
Collect,
Expand Down Expand Up @@ -121,7 +121,7 @@ defmodule Benchee.Benchmark.Runner do
defp run_warmup(
scenario,
scenario_context = %ScenarioContext{
config: %Configuration{warmup: warmup}
config: %{warmup: warmup}
}
) do
measure_runtimes(scenario, scenario_context, warmup, false)
Expand All @@ -130,7 +130,7 @@ defmodule Benchee.Benchmark.Runner do
defp run_runtime_benchmark(
scenario,
scenario_context = %ScenarioContext{
config: %Configuration{
config: %{
time: run_time,
print: %{fast_warning: fast_warning}
}
Expand Down Expand Up @@ -175,7 +175,7 @@ defmodule Benchee.Benchmark.Runner do
defp run_reductions_benchmark(
scenario,
scenario_context = %ScenarioContext{
config: %Configuration{
config: %{
reduction_time: reduction_time
}
}
Expand All @@ -198,7 +198,7 @@ defmodule Benchee.Benchmark.Runner do
defp run_memory_benchmark(
scenario,
scenario_context = %ScenarioContext{
config: %Configuration{
config: %{
memory_time: memory_time
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/benchee/benchmark/scenario_context.ex
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ defmodule Benchee.Benchmark.ScenarioContext do
]

@type t :: %__MODULE__{
config: Benchee.Configuration.t(),
config: Benchee.Benchmark.BenchmarkConfig.t(),
printer: module,
current_time: pos_integer | nil,
end_time: pos_integer | nil,
Expand Down
2 changes: 1 addition & 1 deletion lib/benchee/configuration.ex
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ defmodule Benchee.Configuration do
a map or struct at this point for easier handling in Benchee.
"""
@type t :: %__MODULE__{
parallel: integer,
parallel: pos_integer,
time: number,
warmup: number,
memory_time: number,
Expand Down
33 changes: 17 additions & 16 deletions lib/benchee/profile.ex
Original file line number Diff line number Diff line change
@@ -1,19 +1,4 @@
defmodule Benchee.Profile do
alias Benchee.Benchmark.Collect
alias Benchee.Benchmark.RunOnce
alias Benchee.Benchmark.ScenarioContext
alias Benchee.Output.ProfilePrinter, as: Printer
alias Benchee.Suite

@default_profiler :eprof
@builtin_profilers [:cprof, :eprof, :fprof]
# we run the function a bunch already, no need for further warmup
@default_profiler_opts [warmup: false]

defmodule Benchee.UnknownProfilerError do
defexception message: "error"
end

@moduledoc """
Profiles each scenario after benchmarking them if the `profile_after` option is either set to:
* `true`,
Expand All @@ -31,6 +16,22 @@ defmodule Benchee.Profile do
*excluding* the time of called functions.
"""

alias Benchee.Benchmark.BenchmarkConfig
alias Benchee.Benchmark.Collect
alias Benchee.Benchmark.RunOnce
alias Benchee.Benchmark.ScenarioContext
alias Benchee.Output.ProfilePrinter, as: Printer
alias Benchee.Suite

@default_profiler :eprof
@builtin_profilers [:cprof, :eprof, :fprof]
# we run the function a bunch already, no need for further warmup
@default_profiler_opts [warmup: false]

defmodule Benchee.UnknownProfilerError do
defexception message: "error"
end

@doc """
Returns the atom corresponding to the default profiler.
"""
Expand Down Expand Up @@ -104,7 +105,7 @@ defmodule Benchee.Profile do

RunOnce.run(
scenario,
%ScenarioContext{config: config},
%ScenarioContext{config: BenchmarkConfig.from(config)},
{Collect.Profile, [profiler_module: profiler_module, profiler_opts: profiler_opts]}
)
end
Expand Down
5 changes: 4 additions & 1 deletion test/benchee/benchmark_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ defmodule Benchee.BenchmarkTest do
Suite
}

alias Benchee.Benchmark.BenchmarkConfig

alias Benchee.Benchmark.ScenarioContext
alias Benchee.Test.FakeBenchmarkPrinter, as: TestPrinter
alias Benchee.Test.FakeBenchmarkRunner, as: TestRunner
Expand Down Expand Up @@ -104,8 +106,9 @@ defmodule Benchee.BenchmarkTest do
test "sends the correct data to the benchmark runner" do
scenarios = [%Scenario{job_name: "job_one"}]
config = %Configuration{}
benchmark_config = BenchmarkConfig.from(config)
suite = %Suite{scenarios: scenarios, configuration: config}
scenario_context = %ScenarioContext{config: config, printer: TestPrinter}
scenario_context = %ScenarioContext{config: benchmark_config, printer: TestPrinter}

Benchmark.collect(suite, TestPrinter, TestRunner)

Expand Down