diff --git a/lib/benchee/formatters/html.ex b/lib/benchee/formatters/html.ex index a5143db..e929016 100644 --- a/lib/benchee/formatters/html.ex +++ b/lib/benchee/formatters/html.ex @@ -54,27 +54,23 @@ defmodule Benchee.Formatters.HTML do scenario_data = scenarios - # at best we'd keep the input order here, so no grouping + # at best we'd keep the input order here, so no grouping but its easiest for now |> Enum.group_by(fn scenario -> scenario.input_name end) - |> Enum.map(fn input_to_scenarios = {input_name, _scenarios} -> - # build index data + |> Map.new(fn input_to_scenarios = {input_name, _scenarios} -> {input_name, reports_for_input(input_to_scenarios, system, filename, unit_scaling, inline_assets)} end) index_data = - Enum.map(scenario_data, fn {input_name, {input_index_data, _input_scenarios}} -> - {input_name, input_index_data} + Enum.map(scenario_data, fn {input_name, scenarios} -> + {input_name, Enum.map(scenarios, fn {names, _content} -> names end)} end) - scenario_pages = - Enum.flat_map(scenario_data, fn {_input_name, {_input_index_data, input_scenarios}} -> - input_scenarios - end) + scenario_pages = scenario_data |> Map.values() |> List.flatten() index_page = build_index(index_data, filename, system, inline_assets) - # prolly don't need map here + # prolly don't need map here, but tests explode Map.new([index_page | scenario_pages]) end @@ -192,14 +188,7 @@ defmodule Benchee.Formatters.HTML do end) comparison = comparison_report(input_name, scenarios, system, filename, units, inline_assets) - data = [comparison | scenario_reports] - - # getting a slight variation of the data out may seem weird but since `sequential_output/1` doesn't keep - # the same data around it's done for _some_ consistency and not to delegate knowledge of getting index - # data outside. - index_data = Enum.map(data, fn {names, _content} -> names end) - - {index_data, data} + [comparison | scenario_reports] end defp scenario_report(scenario, system, units, inline_assets) do @@ -249,16 +238,18 @@ defmodule Benchee.Formatters.HTML do end) comparison_report = - {names, _content} = comparison_report(input_name, scenarios, system, filename, units, inline_assets) create_single_file(comparison_report, filename) - [names | scenario_names] + {comparison_names, _content} = comparison_report + + [comparison_names | scenario_names] end defp create_single_file(report, filename) do - # yes wrapping this may feel overdone but provides an easy switch if we introduce a nicer utility to Benchee + # yes wrapping this may feel overdone but provides an easy switch + # if we introduce a nicer utility to Benchee FileCreation.each([report], filename) end @@ -276,9 +267,7 @@ defmodule Benchee.Formatters.HTML do end defp write_index(input_to_names, filename, system, inline_assets?) do - full_index_data = build_index_data(input_to_names, filename) - index_entry = {[], Render.index(full_index_data, system, inline_assets?)} - + index_entry = build_index(input_to_names, filename, system, inline_assets?) create_single_file(index_entry, filename) :ok diff --git a/samples/fast_sequential.exs b/samples/fast_sequential.exs new file mode 100644 index 0000000..a5520a7 --- /dev/null +++ b/samples/fast_sequential.exs @@ -0,0 +1,18 @@ +# It is possible to use multiple formatters so that you have both the Console +# output and an HTML file. +list = Enum.to_list(1..10_000) +map_fun = fn i -> [i, i * i] end + +Benchee.run( + %{ + "flat_map" => fn -> Enum.flat_map(list, map_fun) end, + "map.flatten" => fn -> list |> Enum.map(map_fun) |> List.flatten() end + }, + # kwargs to map conversions + formatters: [ + fn suite -> Benchee.Formatters.HTML.sequential_output(suite, %{auto_open: false}) end + ], + time: 0.05, + memory_time: 0.05, + warmup: 0.01 +) diff --git a/test/benchee/formatters/html_integration_test.exs b/test/benchee/formatters/html_integration_test.exs index 6686148..11e6036 100644 --- a/test/benchee/formatters/html_integration_test.exs +++ b/test/benchee/formatters/html_integration_test.exs @@ -4,12 +4,12 @@ defmodule Benchee.Formatters.HTMLIntegrationTest do @test_directory "test_output" @base_name "my" - @file_path "#{@test_directory}/#{@base_name}.html" + @index_path "#{@test_directory}/#{@base_name}.html" @comparison_path "#{@test_directory}/#{@base_name}_comparison.html" @default_test_directory "benchmarks/output" @default_base_name "results" - @default_file_path "#{@default_test_directory}/#{@default_base_name}.html" + @default_index_path "#{@default_test_directory}/#{@default_base_name}.html" @default_comparison_path "#{@default_test_directory}/#{@default_base_name}_comparison.html" test "works just fine" do @@ -17,13 +17,13 @@ defmodule Benchee.Formatters.HTMLIntegrationTest do time: 0.01, memory_time: 0.01, warmup: 0.02, - formatters: [{Benchee.Formatters.HTML, file: @file_path, auto_open: false}] + formatters: [{Benchee.Formatters.HTML, file: @index_path, auto_open: false}] ] assertion_data = %{ comparison_path: @comparison_path, test_directory: @test_directory, - file_path: @file_path, + index_path: @index_path, base_name: @base_name } @@ -41,7 +41,7 @@ defmodule Benchee.Formatters.HTMLIntegrationTest do assertion_data = %{ comparison_path: @default_comparison_path, test_directory: @default_test_directory, - file_path: @default_file_path, + index_path: @default_index_path, base_name: @default_base_name } @@ -53,13 +53,13 @@ defmodule Benchee.Formatters.HTMLIntegrationTest do time: 0.01, memory_time: 0, warmup: 0.02, - formatters: [{Benchee.Formatters.HTML, file: @file_path, auto_open: false}] + formatters: [{Benchee.Formatters.HTML, file: @index_path, auto_open: false}] ] assertion_data = %{ comparison_path: @comparison_path, test_directory: @test_directory, - file_path: @file_path, + index_path: @index_path, base_name: @base_name } @@ -71,19 +71,41 @@ defmodule Benchee.Formatters.HTMLIntegrationTest do time: 0, memory_time: 0.01, warmup: 0.02, - formatters: [{Benchee.Formatters.HTML, file: @file_path, auto_open: false}] + formatters: [{Benchee.Formatters.HTML, file: @index_path, auto_open: false}] ] assertion_data = %{ comparison_path: @comparison_path, test_directory: @test_directory, - file_path: @file_path, + index_path: @index_path, base_name: @base_name } basic_test(benchee_options, assertion_data, run_time: false) end + test "works just fine using sequential_output" do + benchee_options = [ + time: 0.01, + memory_time: 0.01, + warmup: 0.02, + formatters: [ + fn suite -> + Benchee.Formatters.HTML.sequential_output(suite, %{file: @index_path, auto_open: false}) + end + ] + ] + + assertion_data = %{ + comparison_path: @comparison_path, + test_directory: @test_directory, + index_path: @index_path, + base_name: @base_name + } + + basic_test(benchee_options, assertion_data, run_time: true) + end + test "doesn't crash if we're essentially measuring nothing" do capture_io(fn -> assert %Benchee.Suite{} = @@ -109,29 +131,31 @@ defmodule Benchee.Formatters.HTMLIntegrationTest do ) assert File.exists?(assertion_data.comparison_path) + sleep_path = "#{assertion_data.test_directory}/#{assertion_data.base_name}_sleep.html" - assert File.exists?( - "#{assertion_data.test_directory}/#{assertion_data.base_name}_sleep.html" - ) + assert File.exists?(sleep_path) - assert File.exists?( - "#{assertion_data.test_directory}/#{assertion_data.base_name}_list.html" - ) + list_path = "#{assertion_data.test_directory}/#{assertion_data.base_name}_list.html" + assert File.exists?(list_path) - assert File.exists?(assertion_data.file_path) - html = File.read!(assertion_data.comparison_path) + assert File.exists?(assertion_data.index_path) + comparison_html = File.read!(assertion_data.comparison_path) - assert html =~ "" - assert html =~ "Sleep" - assert html =~ "List" + assert comparison_html =~ "" + assert comparison_html =~ "Sleep" + assert comparison_html =~ "List" if Keyword.get(options, :run_time, false) do - assert html =~ "ips-comparison" + assert comparison_html =~ "ips-comparison" end - assert html =~ "System info" - assert html =~ "benchee version" - assert html =~ "benchee_html version" + assert comparison_html =~ "System info" + assert comparison_html =~ "benchee version" + assert comparison_html =~ "benchee_html version" + + index_html = File.read!(assertion_data.index_path) + assert index_html =~ ~r/href="#{Path.basename(sleep_path)}"/ + assert index_html =~ ~r/href="#{Path.basename(list_path)}"/ end) after if File.exists?(assertion_data.test_directory), do: File.rm_rf!(assertion_data.test_directory)