优化计数器性能

This commit is contained in:
GoEdgeLab
2023-12-24 15:11:09 +08:00
parent 7f38481b48
commit f14d430754
2 changed files with 25 additions and 6 deletions

View File

@@ -54,6 +54,7 @@ func TestCounter_GC(t *testing.T) {
time.Sleep(1 * time.Second)
counter.Increase(1, 20)
counter.GC()
t.Log(counter.Get(1))
}
func TestCounter_GC2(t *testing.T) {
@@ -62,7 +63,7 @@ func TestCounter_GC2(t *testing.T) {
}
var counter = counters.NewCounter[uint32]().WithGC()
for i := 0; i < 1e5; i++ {
for i := 0; i < 100_000; i++ {
counter.Increase(uint64(i), rands.Int(10, 300))
}
@@ -93,6 +94,19 @@ func TestCounterMemory(t *testing.T) {
t.Log((stat1.TotalAlloc-stat.TotalAlloc)/(1<<20), "MB")
t.Log(counter.TotalItems())
var gcPause = func() {
var before = time.Now()
runtime.GC()
var costSeconds = time.Since(before).Seconds()
var stats = &debug.GCStats{}
debug.ReadGCStats(stats)
t.Log("GC pause:", stats.PauseTotal.Seconds()*1000, "ms", "cost:", costSeconds*1000, "ms")
}
gcPause()
_ = counter.TotalItems()
}
func BenchmarkCounter_Increase(b *testing.B) {

View File

@@ -7,9 +7,10 @@ import (
)
const spanMaxValue = 10_000_000
const maxSpans = 10
type Item[T SupportedUIntType] struct {
spans []T
spans [maxSpans + 1]T
lastUpdateTime int64
lifeSeconds int64
spanSeconds int64
@@ -19,16 +20,16 @@ func NewItem[T SupportedUIntType](lifeSeconds int) *Item[T] {
if lifeSeconds <= 0 {
lifeSeconds = 60
}
var spanSeconds = lifeSeconds / 10
var spanSeconds = lifeSeconds / maxSpans
if spanSeconds < 1 {
spanSeconds = 1
} else if lifeSeconds > maxSpans && lifeSeconds%maxSpans != 0 {
spanSeconds++
}
var countSpans = lifeSeconds/spanSeconds + 1 /** prevent index out of bounds **/
return &Item[T]{
lifeSeconds: int64(lifeSeconds),
spanSeconds: int64(spanSeconds),
spans: make([]T, countSpans),
lastUpdateTime: fasttime.Now().Unix(),
}
}
@@ -119,5 +120,9 @@ func (this *Item[T]) IsExpired(currentTime int64) bool {
}
func (this *Item[T]) calculateSpanIndex(timestamp int64) int {
return int(timestamp % this.lifeSeconds / this.spanSeconds)
var index = int(timestamp % this.lifeSeconds / this.spanSeconds)
if index > maxSpans-1 {
return maxSpans - 1
}
return index
}