-
Notifications
You must be signed in to change notification settings - Fork 65
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
Warn if the benchmarking function is evaluating #358
Conversation
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.
Heyo, thanks for your contribution!
Sorry it took me so long to get around here... busy times.
I left some comments in line. Besides that, I also wonder how to test this.
I was thinking if one could launch iex -S mix
and then hand it the input to do a Benchee.run
, capture the output and see the message. That might be overdoing it and I didn't manage to get it to go as I couldn't make -S
and -e
work together.
The other way would be to make the function that checks if the function is being evaluated injectable so that for test purposes we could turn it to true once. Might be overdone for a simple printing message, but I still think about it 😁
Cheers & thanks,
Tobi
lib/benchee.ex
Outdated
@@ -55,6 +55,14 @@ for {module, moduledoc} <- [{Benchee, elixir_doc}, {:benchee, erlang_doc}] do | |||
|
|||
defp add_benchmarking_jobs(suite, jobs) do |
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 function isn't the best one to add it to, this will only be triggered for Benchee.run/2
- which is not the best as calling Benchee.benchmark
manually is also a valid interface.
So this should rather live around Benchee.benchmark
or some of the functions it calls: https://github.com/bencheeorg/benchee/blob/main/lib/benchee/benchmark.ex#L27-L36
lib/benchee.ex
Outdated
IO.puts(""" | ||
Warning: the benchmark #{key} is using an evaluated function. | ||
Evaluated functions perform slower than compiled functions. | ||
Consider moving all of the Benchee caller to a function in a module and invoking the `Mod.fun()` instead. |
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.
In the Benchee.Benchmark
module you'll see that there is a dedicated printer module to cover printing of text messages (for testability but also separation of concerns).
As for the warning itself, I think we'd also need to tell folks that they can put the benchmark into a benchmark.exs
file and just mix run benchmark.exs
- that also works to avoid this. Might bloat up the message a bit too much and we might wanna link to some wiki/README instead. Not sure. See what you think :)
lib/benchee.ex
Outdated
@@ -55,6 +55,14 @@ for {module, moduledoc} <- [{Benchee, elixir_doc}, {:benchee, erlang_doc}] do | |||
|
|||
defp add_benchmarking_jobs(suite, jobs) do | |||
Enum.reduce(jobs, suite, fn {key, function}, suite_acc -> | |||
if is_function(function) && :erlang.fun_info(function, :module) == {:module, :erl_eval} do |
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.
As you said you didn't deal with the tuple version here. I think we need to deal with it though, although it's not often used it should still work :)
Iirc it is {function, kwlist}
so a pattern match to extract the function we want to check should be rather easy.
(the test failure isn't your failt, just gotta rebase/merge with main) |
Hey @PragTob, just want to let you know what we got together last weekend to work on this PR. All comments have been handled, the only thing left to do is figure out how to test this. We plan to get together next weekend on Saturday to hopefully finish it up. |
@BrooklinJazz thanks for the update! Might as well be too hard to test, feel free to push the code and I might chime in. Sometimes testing isn't worth the effort (sadly). Try is important, but don't bind it to that or break your backs trying to do that. |
Co-authored-by: aar2dee2 <aar2dee2@users.noreply.github.com> Co-authored-by: ReecesPeanutButterCodes <ReecesPeanutButterCodes@users.noreply.github.com> Co-authored-by: Justin Morgan <justin-m-morgan@users.noreply.github.com> Co-authored-by: Tom <BigTom@users.noreply.github.com> Co-authored-by: Jeremy Brayton <w0rd-driven@users.noreply.github.com> Co-authored-by: Russell Baker <3triangles@users.noreply.github.com>
Thank you @PragTob! I've pushed the changes so you can have a look. I'm really curious to try your recommended solution of launching the IEx shell (not sure how to do that from a test, would appreciate it if you have any tips). If that doesn't work I think we could use a mock. Maybe the test isn't worth it for the sake of getting this PR in, that's up to you! But, I'd still love to circle around to it and try it during our next Saturday session. Wanted to say thank you again @PragTob! Your feedback really helped our learning group :) |
Hey there, live was busier than expected again :( So... for launching iex with Benchee I couldn't quite get it done somehow... theoretically it should be possible by launching a process that launches Let me see if I can get it to work 😁 (might take some time, am at a conference and as I said it was full). I usually like to have test and thing go in together, but as you said correctly (and I think me too) might not be worth it here though. |
I'm 100% sure that I was being stupid when it comes to receiving messages but this script should work as the basis for a test, might implement it 😁
|
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 @PragTob! Appreciate your help with this one! |
Merging as #365 with the added changes, thanks y'all a lot! |
And it was merged, thanks y'all! |
First time contributing to benchee, please let me know how I can improve this PR! 🙏
This was done in a group with @czrpb, @aar2dee2, and @ReecesPeanutButterCodes.
Attempting to warn if the benchmarking function is evaluated instead of compiled based on #355 .
We were not sure how to best present the warning, and could not find previous examples to follow. Please let me know if there
is a better way than a multiline
IO.puts
We opted to only handle when the benchmarked function is a function, rather than when it's a tuple.
Resolves #355