-
Notifications
You must be signed in to change notification settings - Fork 66
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
First version of separating memory and runtime measurements #204
Conversation
Introduces a new `Measurer` behaviour that can be adopted by `Time` and `Memory` and in the future `Reduction`. Also switches over to memory having its own configuration for time. Like how this ended up in general. This isn't merge ready yet, it's a first implementation already up for review and CI. TODO: - [ ] README/documentation adjustments - [ ] respect `memory_time` during calculation of estimated total runtime - [ ] allow measurer to return `nil` when a a measurement "failed" and handle it appropriately (memory measurement is less than 0 case)
@@ -146,7 +146,7 @@ defmodule Benchee.Benchmark.RunnerTest do | |||
assert [memory_consumption] = Enum.uniq(memory_usages) | |||
assert memory_consumption >= 1 | |||
# depending on the number iterations determined, there can be spikes/changes | |||
assert memory_consumption <= 100 | |||
assert memory_consumption <= 1_000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
woopsie I added a 0 here! ;)
Before this was run in the repeated code with a num_iterations
of 100 or 10. It seems that we have some small basic overhead that now shows up again more. We can have a look at removing this some time later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wrote a small script and memory usage for an empty function without anything seems to be 616 Byte on my machine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This turned out nicely! What do you think about changing the behavior name to Measure
? I think it would improve readability. Like when you pass Measure.Time
as an argument. And it is easier to type/pronounce! :)
lib/benchee/benchmark/runner.ex
Outdated
alias Benchee.Benchmark.{Scenario, ScenarioContext} | ||
alias Benchee.Utility.{RepeatN, Parallel} | ||
alias Benchee.Configuration | ||
alias Benchee.Benchmark.Measurer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe place this alias with the others from Benchmark
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah damn me, totally - thanks Eric!
Good idea on the naming too, thanks! I think that was my OOP mindset leaking through as in the thing that measures but just |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a great start!
My only concern at the moment is with naming. In our configuration, the keys time
and memory_time
don't make it clear that they're exclusive of one another. I could see people thinking that memory_time
is how much of the time
we want to devote to measuring memory.
That said, this might be able to be cleared up just with documentation. It would be awesome if we could come up with something that didn't require documentation to make that clear, but nothing is coming to me yet this morning. I'll keep thinking about it, though 😄
Yeah nothing comes to my mind as well. That was one of my concerns with these... we could rename |
Since we're still pre-1.0, now would be the time to make those breaking changes if we feel they're the best way to go 😉 However, |
but what good would chaning it from time to duration be? I think it's better if the times always just add to each other - because if they sort of divide the time amongst each other all sorts of edge cases pop up... :( |
* Fixes #206 * Also make sure that we're not printing that we are "benchmarking"
Includes a fix for #206 now :) edit: as it includes another fix now but they are all relatively separate, reviewing commits separately might help :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great! Just one little documentation thing that I think might be helpful, and then it's ready to go.
IO.puts "Available memory: #{available_memory}" | ||
IO.puts "Elixir #{elixir_version}" | ||
IO.puts "Erlang #{erlang_version}" | ||
IO.puts """ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you 👍
README.md
Outdated
@@ -143,6 +145,7 @@ The available options are the following (also documented in [hexdocs](https://he | |||
|
|||
* `warmup` - the time in seconds for which a benchmarking job should be run without measuring times before real measurements start. This simulates a _"warm"_ running system. Defaults to 2. | |||
* `time` - the time in seconds for how long each individual benchmarking job should be run and measured. Defaults to 5. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this should be updated to make it super clear that this is only to measure the runtime performance?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah definitely, good catch - thank you! I'll do that tomorrow :)
``` | ||
|
||
Memory time can be specified separately as it will often be constant - so it might not need as much measuring time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙏
Assuming that this is good now --> (devon's comments where documentation related I think I fixed those and if not we can always adjust again) |
Introduces a new
Measurer
behaviour that can be adopted byTime
and
Memory
and in the futureReduction
. Also switches over tomemory having its own configuration for time. Like how this ended up
in general.
This isn't merge ready yet, it's a first implementation already
up for review and CI.
Fixes #202
Ah yeah, most important proof - it actually fixes the problem - memory measurements don't seem to be impacting runtime measurements anymore:
TODO:
memory_time
during calculation of estimated total runtimenil
when a a measurement "failed" and handle it appropriately (memory measurement is less than 0 case)This also sort of sets up putting
do_benchmark/3
into its own module as it is responsible for running the benchmarking with a given measurer. The rest of the module deals with setting up the measurements according to our different measurer.