-
Notifications
You must be signed in to change notification settings - Fork 780
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
Histogram Record Method Benchmark #2754
Changes from 5 commits
61a8ab8
5ad482c
00970cb
2cfd185
3126157
a5efd0e
9cecddc
6158988
a178715
30da4bb
ba40004
700c7bb
33c402d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -247,12 +247,18 @@ internal void Update(double number) | |||||||||||
case AggregationType.Histogram: | ||||||||||||
{ | ||||||||||||
int i; | ||||||||||||
for (i = 0; i < this.histogramBuckets.ExplicitBounds.Length; i++) | ||||||||||||
if (double.IsNaN(number)) | ||||||||||||
{ | ||||||||||||
// Upper bound is inclusive | ||||||||||||
if (number <= this.histogramBuckets.ExplicitBounds[i]) | ||||||||||||
i = this.histogramBuckets.ExplicitBounds.Length; | ||||||||||||
} | ||||||||||||
else | ||||||||||||
{ | ||||||||||||
// If `number` is not a histogram bound, the result will be negative | ||||||||||||
// The bitwise complement of the returned value is the insertion index | ||||||||||||
i = Array.BinarySearch(this.histogramBuckets.ExplicitBounds, number); | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For histogram with small number of bounds, this extra invocation could turn out to be slower. We need to have a perf benchmark to show the numbers (especially for low buckets). Refer to the prom-client and see how low/high buckets are handled differently: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll write a self-contained benchmark that compares the existing linear search implementation with the binary search one and run it with a range of boundary counts. I agree that linear is likely faster for a small number of boundaries, but eventually the binary search will outperform it. Then I can a boundary number where anything less uses linear, and anything more uses binary. I'll generate the random numbers so that each index gets an equal amount of finds.
|
||||||||||||
if (i < 0) | ||||||||||||
{ | ||||||||||||
break; | ||||||||||||
i = ~i; | ||||||||||||
} | ||||||||||||
} | ||||||||||||
|
||||||||||||
|
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.
Interesting... 🤔 makes me wonder if
NaN
should be an error case that we just log instead of recording.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.
Ya, I'm not sure. I was trying to fix the Prometheus exporter test for
PrometheusSerializerTests.HistogramNaN
since I was trying to compare by using the==
operator and alsodouble.NaN
returnsFalse
for it appears all uses of<
,>
,==
, etc.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.
Yea, doesn't make sense to me that we should increment the largest bucket... why not the smallest? or even a random one?
Interestingly, I checked the Java SDK, and it turns out they too increment the last bucket. Wonder if this is just accidental because I don't see anything in the spec.
Though I looked at that prometheus test and noted that
NaN
is a valid value in the prometheus format.Maybe something @reyang could shed some light on.
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.
The SDK Specification gives certain flexibility to the SDK implementations for perf consideration.
Prometheus Exporter spec (which is still Experimental) hasn't covered
NaN
histogram yet, further clarifications are needed.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.
If perf is what drives our decision then it would make sense to try and eliminate the
if (double.IsNaN(number))
check.If we settle on using
Array.BinarySearch
then~Array.BinarySearch(buckets, double.NaN)
equals 0. Seems it would be slightly more efficient to increment the first bucket in this case.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.
Though, the bummer of aggregating a
NaN
value is that it not only messes up one of the bucket counts, it also clobbers the sum.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.
+1
This is also called out in the spec:
It is unspecified how the SDK should handle the input limits. The SDK authors MAY leverage/follow the language runtime behavior for better performance, rather than perform a check on each value coming from the 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.
In addition to
NaN
, other values could result inNaN
as well, for example (note that currently histogram does not support negative value):