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

Extract runner and move to scenarios #96

Merged
merged 7 commits into from Jul 23, 2017
Merged

Extract runner and move to scenarios #96

merged 7 commits into from Jul 23, 2017

Conversation

devonestes
Copy link
Collaborator

Ok, this is a biggie, so I tried to have each commit be a standalone piece that could be reviewed on its own. I took a pretty methodical approach, so hopefully if you follow the commits you'll get a sense of the changes I made at each step.

It still feels a little "incomplete" without the memory usage stuff in there - especially the console formatter - but all tests are passing and it feels to me like it's in a good place now.

This commit has Benchee.Benchmark refactored and in good shape
(including documentation) after extracting the new runner from that
module. The implementation at this point is still pretty much broken,
but next is to get the runner up to shape and tested. Once the runner
is implemented and tested, then we'll need to update the statistics.
At this point pretty much all the test and code for
`Benchee.Benchmark.Runner` is good to go. Next up is re-doing the
statistics to add that stuff to the scenarios instead of to a map on
the suite.
This was an easy update! Now `Benchee.Statistics` is good and all tests
are updated and passing for that module.
This commit updates the console formatter and associated tests, as well
as the top level integration tests since this was the last step in the
rough refactoring. There is some additional cleanup I'd like to do
(like changing some names and such), but I wanted to at least get the
suite green before I did any additional cosmetic things.

Yay - the hard part is done!
I forgot we had those old keys in `%Benchee.Suite{}` that could be
removed at this point, so I did that and updated the associated tests.
@@ -0,0 +1,21 @@
defmodule Benchee.Benchmark.ScenarioContext do
defstruct [
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the fast warning and run_time here pretty much just so I
had a consistent way of running warmups and real runs without having to have
additional information. It's essentially duplicating data from the config,
though. Is this a problem?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like a smell to me :)

Also, on further inspection - why do we carry along the whole config when the only values we seem to be using are warmup, run_time and show_fast_warning? (If I didn't forget anyone)

We could just pick those values from the configuration and drop the configuration itself in the ScenarioContext imo. Anything speaking against this?

I somehow also don't feel like updating the ScenarioContext for the warmup is necessarily the best as I see it more immovable than this and a bit confusing (as it's the context for the whole scenario, if it changes based on warmup adn run time there might be another ExecutionContext but that seems like overkill). I feel like passing the benchmarking function the time it should run for would still be viable but I'd need to play with that to see how many arguments it adds where. Would like to play with that after this is merged, so definitely can go ahead with the ScenarioContext being adjusted. Would still like to explore dropping the dependency on configuration :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like we're using the whole config when passed to the printer for a function here: https://github.com/PragTob/benchee/pull/96/files#diff-402aedd43cbd599699f2ab3157ffdf8aR34 and here: https://github.com/PragTob/benchee/pull/96/files#diff-402aedd43cbd599699f2ab3157ffdf8aR35

We also use parallel here: https://github.com/PragTob/benchee/pull/96/files#diff-402aedd43cbd599699f2ab3157ffdf8aR36

I think for now, leaving config as a whole in the ScenarioContext is a good first step, especially since I'm not 100% sure how all this will change with the introduction of measuring memory usage...

Ok, back to playing around with removing those duplicate values!

Some of the function names didn't fit anymore, so I updated them,
changed some typespecs, and used the shorthand function definition in a
few places.
@PragTob
Copy link
Member

PragTob commented Jul 13, 2017

FYI le me is 🤧 so sorry the review will still take a while :'(

@devonestes
Copy link
Collaborator Author

No problem - feel better! 😷

Copy link
Member

@PragTob PragTob left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thank you a ton for the amount of work you put into this! 💚 👍

After all this, I believe you deserve a good nap.

img_20170713_145446

The biggest discussion point I can think of as of now, is what goes into ScenarioContext et. al. but the discussion point for that is higher up.

I"m really positive for this to land soon 🙂

edit: oh yeah the & stuff, we could leave it in and I just remove it later or you convince me that it's amazing :)

for `warmup` time without gathering results and them running them for `time`
gathering their run times.

This means the total run time of a single benchmarking job is warmup + time.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

more precisely benchmarking scenario :)

config: %Configuration{warmup: warmup}
}) do
warmup_context = %ScenarioContext{scenario_context | show_fast_warning: false,
run_time: warmup}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm yeah not a huge of duplicating these keys alongside having them in config, first thought was "wait... can you do this, this has to be on config, doesn't it?" More comments on the struct :)

}
try_n_times(scenario, new_context)
end
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still look at this and I wanna make try_n_times and determine_n_times one. Not here, alas.

@@ -0,0 +1,21 @@
defmodule Benchee.Benchmark.ScenarioContext do
defstruct [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like a smell to me :)

Also, on further inspection - why do we carry along the whole config when the only values we seem to be using are warmup, run_time and show_fast_warning? (If I didn't forget anyone)

We could just pick those values from the configuration and drop the configuration itself in the ScenarioContext imo. Anything speaking against this?

I somehow also don't feel like updating the ScenarioContext for the warmup is necessarily the best as I see it more immovable than this and a bit confusing (as it's the context for the whole scenario, if it changes based on warmup adn run time there might be another ExecutionContext but that seems like overkill). I feel like passing the benchmarking function the time it should run for would still be viable but I'd need to play with that to see how many arguments it adds where. Would like to play with that after this is merged, so definitely can go ahead with the ScenarioContext being adjusted. Would still like to explore dropping the dependency on configuration :)

]

@type t :: %__MODULE__{
config: map,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we keep config, this could use the configuration type? :)

jobs
|> Enum.flat_map(fn({_name, job}) -> Map.to_list(job) end)
scenarios
|> Enum.flat_map(&(Map.to_list(&1.run_time_statistics)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I might just go through here later and convert them back to fn or you convince me why & is great, always happy to learn :)

alias Benchee.Suite
alias Benchee.Benchmark
alias Benchee.Configuration
alias Benchee.Statistics
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think most places use the one line aliasing? :)

suite.scenarios
|> Enum.filter_map(filter_fun, map_fun)
|> List.flatten()
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is something we eventually wanna provide on Suite, one of the downsides of the new approach. I guess this might become more relevant when working on bringing the plugins up to date which I sort of dread :D

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy to help with the other plugins, but maybe we would want to wait until we implement the memory usage info anyway? I anticipate the console formatter module to change significantly once that's implemented, and I'd imagine we'd need similar changes to the other plugins as well...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm true/it's an idea. Imo new formatter versions don't need to support memory usage straight away and that could be released later. The general access to data still needs to change and I think the implementation of memory usages is more of just adding an extra section, it shouldn't interfere as much with the other/existing code imo

end

test "can run multiple benchmarks in parallel" do
suite = test_suite(%Suite{configuration: %{parallel: 6, time: 60_000}})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now that I see it here, 6 seems like overkill. Sticking to just 4 should work just as fine, no biggy and not related though :D

end,
fn(suite) -> IO.puts suite.configuration.assigns.custom end
]
formatters: [formatter_one, formatter_two, formatter_three]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

In this commit I'm updating some things according to feedback on the
previous commits. I'm removing the &() functions, fixing a doctest that
was incorrect (but still passed for some reason), and a couple other
small things.
@PragTob
Copy link
Member

PragTob commented Jul 21, 2017

ah yeah, FYI I think this is good I just wanted to take a calm moment on the weekend to give it one more read and then merge

Copy link
Member

@PragTob PragTob left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a ton! 👍

Ghost is happy how all of this came together

img_20170723_143731

@PragTob PragTob merged commit 3e5a84b into bencheeorg:master Jul 23, 2017
@devonestes devonestes deleted the extract-runner branch July 23, 2017 18:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants