Skip to content

Commit fa0332a

Browse files
Merge pull request #46 from HdrHistogram/cpu.optimize.nextCountAtIdx
[perf] optimize ValueAtPercentile(s): introduce nextCountAtIdx() and reduce by 25.6% the on-cpu usage
2 parents 35c7773 + 164c49c commit fa0332a

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

hdr.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ func (h *Histogram) ValueAtPercentile(percentile float64) int64 {
335335
countAtPercentile := int64(((percentile / 100) * float64(h.totalCount)) + 0.5)
336336

337337
i := h.iterator()
338-
for i.next() {
338+
for i.nextCountAtIdx() {
339339
total += i.countAtIdx
340340
if total >= countAtPercentile {
341341
if percentile == 0.0 {
@@ -372,7 +372,7 @@ func (h *Histogram) ValueAtPercentiles(percentiles []float64) (values map[float6
372372
total := int64(0)
373373
currentQuantileSlicePos := 0
374374
i := h.iterator()
375-
for currentQuantileSlicePos < totalQuantilesToCalculate && i.next() {
375+
for currentQuantileSlicePos < totalQuantilesToCalculate && i.nextCountAtIdx() {
376376
total += i.countAtIdx
377377
for currentQuantileSlicePos < totalQuantilesToCalculate && total >= countAtPercentiles[currentQuantileSlicePos] {
378378
currentPercentile := percentiles[currentQuantileSlicePos]
@@ -621,8 +621,8 @@ type iterator struct {
621621
highestEquivalentValue int64
622622
}
623623

624-
// Returns the next element in the iteration.
625-
func (i *iterator) next() bool {
624+
// nextCountAtIdx does not update the iterator highestEquivalentValue in order to optimize cpu usage.
625+
func (i *iterator) nextCountAtIdx() bool {
626626
if i.countToIdx >= i.h.totalCount {
627627
return false
628628
}
@@ -640,8 +640,15 @@ func (i *iterator) next() bool {
640640
i.countAtIdx = i.h.getCountAtIndex(i.bucketIdx, i.subBucketIdx)
641641
i.countToIdx += i.countAtIdx
642642
i.valueFromIdx = i.h.valueFromIndex(i.bucketIdx, i.subBucketIdx)
643-
i.highestEquivalentValue = i.h.highestEquivalentValue(i.valueFromIdx)
643+
return true
644+
}
644645

646+
// Returns the next element in the iteration.
647+
func (i *iterator) next() bool {
648+
if !i.nextCountAtIdx() {
649+
return false
650+
}
651+
i.highestEquivalentValue = i.h.highestEquivalentValue(i.valueFromIdx)
645652
return true
646653
}
647654

0 commit comments

Comments
 (0)