-
-
Notifications
You must be signed in to change notification settings - Fork 83
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
Some minor optimizations #483
Conversation
Commit that adds benchmark is not necessary, I can drop it or change to use criterion. |
Should be working now. |
a642ad4
to
9821c93
Compare
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 a lot for your work! I have a few comments. I understand why you made set_counting
part of the State
trait, but I'd rather not expose this functionality that way. Is it possible to make it part of the interface of the various states, but not the State
trait?
This essentially highlights some of the issues I have with the current design of state handling (#478). I will have to think about it, but that may take a bit.
Btw, have you tried whether making line 224 in executor.rs
optional helps? Unfortunately I can't make a review comment there because the PR doesn't touch this code. I mean this line:
state.func_counts(&self.problem);
I understand that it does not remove all counts handling, but I'm just interested how that affects performance.
Finally I would prefer to not have the benchmark as part of this PR, but you can of course keep it in the PR until it is ready to be merged.
*count = v | ||
if self.counting_enabled { | ||
for (k, &v) in problem.counts.iter() { | ||
let count = self.counts.entry(k.to_string()).or_insert(0); |
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.
By the way, have you been able to find out whether hashing is the problem or the allocation of .to_string()
? In case it was the latter, I was wondering if Cow
would help?
If it's hashing, I was wondering if replacing HashMap<String, u64>
with HashMap<SomeEnum, u64>
would help, where
enum SomeEnum {
CostCount,
GradientCount,
OperatorCount,
JacobianCount,
HessianCount,
AnnealCount,
Other(String),
}
(or something along those lines). That would cover all the function calls that in argmin, but also allows one to count function calls defined in external code via Other
. It also avoids .to_string()
.
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 far as I remember it's 35% allocation and 65% hashing. HashMap
is DoS resistant by default. Changing the hash function or switching to BTreeMap
combined with enum approach you propose might help a bit I guess, but this changes public API.
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.
I don't mind changing the public API in that case. Why do you propose a BTreeMap
instead of a HashMap
? Hashing an enum should be quick (I expect it to use it's integer representation as a hash with a bit of additional overhead for hashing Other(String)
). Anyway I think this goes beyond this PR and can certainly be left as a future improvement.
Should be possible for as long as I don't add "enabled if observers are present". Since you suggest to remove that logic - I can move it to part of the each interface. Will try that today.
This removes about half of the overhead related to counting I think. Better than nothing
Absolutely, I just wanted to show what exactly I'm measuring. Will drop before merging. |
|
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.
Apologies for the very late reply, unfortunately I wasn't able to get to it earlier.
*count = v | ||
if self.counting_enabled { | ||
for (k, &v) in problem.counts.iter() { | ||
let count = self.counts.entry(k.to_string()).or_insert(0); |
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.
I don't mind changing the public API in that case. Why do you propose a BTreeMap
instead of a HashMap
? Hashing an enum should be quick (I expect it to use it's integer representation as a hash with a bit of additional overhead for hashing Other(String)
). Anyway I think this goes beyond this PR and can certainly be left as a future improvement.
By default |
New changes:
|
Fixed the failing test. FWIW I'm getting test failures around the places I never touched... This one is related to floating point accuracy - probably EPSILON is too large..
Not sure what is this about at all
|
I suspect you need to rebase onto main. There was a Rust version update and that typically causes new clippy lints to fail, but that was fixed in #488 .
We've had this before -- it typically only fails locally, not in the CI. We couldn't figure out why ... if it does fail in the CI too I'm happy to increase the epsilon, but judging from the current state of the CI run, it seems to pass.
That's really strange... but it seems to pass in the CI. I hope to be able to do another review today! :) |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #483 +/- ##
==========================================
- Coverage 92.11% 92.09% -0.03%
==========================================
Files 178 178
Lines 24398 24455 +57
==========================================
+ Hits 22475 22521 +46
- Misses 1923 1934 +11 ☔ View full report in Codecov by Sentry. |
Done. In fact I have scripts to automagically rebase onto origin/master, then someone smart decided to rename the default branch. |
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.
LGTM, thanks a lot!
after:
before:
Fixes #482