-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Faster h.findBucket(v)
#1662
Faster h.findBucket(v)
#1662
Conversation
cce97b4
to
e3911b2
Compare
That's really cool @imorph, I didn't have the time to look deep into this but just skimmed over the changes. One question, how did you come up with the 35 limit? Was just intuition or backed by evidence? There's no wrong answer, I'm just curious :) |
@ArthurSens I made bite-size research here -> https://github.com/imorph/go-search-research where benchmarks were executed for many different lengths of slice. On both x86 and M3 slice length where binary search starts to take over was somewhere in between 30 and 40 (it also depends on a position of an element in a slice - the closer to beginning the lengthier slice should be for binary search to win). |
I plan to review this PR this weekend. Sorry for the tardiness. |
One more before/after diff on another CPU (+ one test added):
|
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.
Similar to the other PR, let's add a comment explaining that numbers were chosen based on empirical testing while linking to your PR description.
I've added some comments about early exits and then LGTM!
prometheus/histogram.go
Outdated
n := len(h.upperBounds) | ||
|
||
// Early exit: if v is less than or equal to the first upper bound, return 0 | ||
if v <= h.upperBounds[0] { | ||
return 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.
Should we swap the order here between the early exit and n := ...
just so it truly is an early exit? :o)
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.
Seems like there is cases when len(h.upperBounds) == 0
so we should first check for len
otherwise TestNativeHistogram
panics at factor 1.1 results in schema 3
prometheus/histogram.go
Outdated
// Early exit: if v is greater than the last upper bound, return len(h.upperBounds) | ||
if v > h.upperBounds[n-1] { | ||
return n | ||
} |
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.
Could we move this part upwards? Even before the linear search?
By the way, awesome research here: https://github.com/imorph/go-search-research |
d6d7c58
to
aaa3f32
Compare
@imorph looks like you added some extra commits by accident 🤔 |
yes, sorry for the this git-mess =(
I can reset to main this branch, and put everything new on top for more clearer picture. WDYT? |
No worries! Yeah, ideally we have only the relevant commits in this PR, so rebasing on main sounds like a good idea |
e3cc4e4
to
0c73c1c
Compare
@ArthurSens this PR closed itself after me trying to start from fresh main. #1673 is what it should be from the start. latest version comparison with main on apple M3:
interesting that I don't see any significant improvements for basic cases (that were documented in PR description). May be this is some intel specifics or measurement artefact |
What problem this PR is solving
Hi!
It is part "two" of exploration for optimization possibilities for cockroachdb/cockroach#133306 (part "one" is here). Second largest contributor in original issue was
findBucket
function. Closer look at that function revealed some excellent suggestion from @beorn7 about smaller-sized arrays and linear search:I decided to explore it in isolation and this is a result: https://github.com/imorph/go-search-research
TLDR:
+Inf
bucket (regardless the size)This PR is proposal to use this "adaptive" implementation
Design
+Inf
before calling intosort.SearchFloat64s
sort.SearchFloat64s
for everything elseResults
+Inf
new implementation is better by 90% (no need to execute full binary search just check last element)@vesari
@ArthurSens
@bwplotka
@kakkoyun