-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Improve equals check #22778
Improve equals check #22778
Conversation
Pinging @elastic/integrations-services (Team:Services) |
Nice!!! Have you considered to turn
alternatively one can try functions as well like:
equalsValue is internal, so we can play with it. Just wondering which implementation would be the fastest here. All in all I would prefer to move the loop body into a method on |
Thanks for the review. Both look to be more elegant ways to me. I was trying to implement this and notice that it seems that in both implementation
Another notice is that warning logs will not be logged anymore after this change, since for a field |
Yes, this is a concern. If checks do not work as expected for all events due to type mismatches, then the logs will point this out.
Ah, you are right. Didn't notice that value is an interface. In that case we would have |
yeah, I think the difference would be 1. previously warning logs is about all type are mismatched 2. now it warns if the value is not its wanted type. For example, if I have a config The result is still the same though. |
I would say this is an improvement :) Plus the old code did not take the type in the config in mind when comparing the results. E.g. if The change will: improve performance, improve log output, fix potentially wrong matches. |
Hi, I've added both implementation in the code for now for your reference, the benchmark result is attached below, overall it seems the implementation with new type wrapping int/str/bool has better performance, but I am a bit confused why it shows a lower than others when there are less checks, which I couldn't figure out at this moment..
|
It looks like the performance depends on the number of allocations. I modified your benchmark function to GC before a run and reset the timer, such that we only test the
With this change the numbers for comparisons that did not fail like
All in all the solution that allocates less will be the fastest:
Equals2 was faster when it did allocate once, but for the With3Conditions test it was slower because it has had 4 allocations. Time to profile:
This command will open an interactive window in your browser that allows you to inspect the run. In the grapgh click on
This is funny. Why does the Equals2 check logs a message and the others not? The The performance between good path (types match) and bad path (type mismatch) seems to differ quite heavily thanks due to the extra allocations. Looking at the runs without allocations I'd say it doesn't make a big difference which of the three solutions we use, them seem to be similar performance wise: my run:
a few ns/op difference is negligible and looks like noise. I'd concentrate on the "good" path only first (just update the benchmark, such that no type errors are printed), select one of these implementations, and finally use the benchmark and memory profile to reduce allocations in the bad path. Just for fun (equals 3 with allocating the logger upfront per equal function):
running the benchmark I get:
The single allocation is due the logger doing |
oops this is my fault.. I debugged equals2 finally got why it hits the logger statement in 3Condition test of equals2, it should be
and after that I am getting expected output
Now seems equals3 is the choice, and as you have mentioned, I have updated the code to adopt equals3 and cleaned other code. Please have a review. Below is the new benchmark with the GC and reset timer prior to the benchmark loop.
It's been very helpful, I really appreciate it! |
jenkins run the tests please |
The change looks good to me. Thank you, this is a really great improvement in the hot code paths! Do you by any chance have a benchmark run (with the new benchmarks) for the old code? I'd love to see how much performance has improved. You might want to check out benchcmp (e.g. see this blog post, not by me, just a random google search) I started CI and will merge and port the change to the release branches if CI goes green. |
Merged. The improvement should become available with the 7.11 release. Thanks for the contribution! Performance improvements like this are really exciting! |
Thanks @urso . Please check comparison below.
|
(cherry picked from commit 5f3d8ac)
What does this PR do?
Improve equals check performance
Why is it important?
Checklist
I have commented my code, particularly in hard-to-understand areasI have made corresponding changes to the documentationI have made corresponding change to the default configuration filesCHANGELOG.next.asciidoc
orCHANGELOG-developer.next.asciidoc
.Author's Checklist
How to test this PR locally
Benchmark test
Logs
Benchmark added test case, before this change
After