app/vmselect/netstorage: reduce the number of allocations for blockRefs objects in ProcessSearchQuery()

This should reduce pressure on Go GC at vmselect

The change has been extracted from https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5527
This commit is contained in:
Aliaksandr Valialkin 2024-01-22 21:16:38 +02:00
parent 2ab9a75cca
commit b289f15f02
No known key found for this signature in database
GPG Key ID: 52C003EE2BCDB9EB

View File

@ -1353,9 +1353,13 @@ type tmpBlocksFileWrapper struct {
orderedMetricNamess [][]string orderedMetricNamess [][]string
// metricNamesBufs are per-worker bufs for holding all the loaded unique metric names. // metricNamesBufs are per-worker bufs for holding all the loaded unique metric names.
// It should reduce pressure on Go garbage collector by reducing // It should reduce pressure on Go GC by reducing the number of string allocations
// the number of memory allocations when constructing metricName string from byte slice. // when constructing metricName string from byte slice.
metricNamesBufs [][]byte metricNamesBufs [][]byte
// addrssBufs are per-worker bufs for holding all the blockAddrs across all the loaded time series.
// It should reduce pressure on Go GC by reducing the number of blockAddrs object allocations.
addrssBufs [][]blockAddrs
} }
type blockAddrs struct { type blockAddrs struct {
@ -1363,10 +1367,17 @@ type blockAddrs struct {
addrs []tmpBlockAddr addrs []tmpBlockAddr
} }
func newBlockAddrs() *blockAddrs { func (tbfw *tmpBlocksFileWrapper) newBlockAddrs(workerID uint) *blockAddrs {
ba := &blockAddrs{} addrssBuf := tbfw.addrssBufs[workerID]
ba.addrs = ba.addrsPrealloc[:0] if cap(addrssBuf) > len(addrssBuf) {
return ba addrssBuf = addrssBuf[:len(addrssBuf)+1]
} else {
addrssBuf = append(addrssBuf, blockAddrs{})
}
addrs := &addrssBuf[len(addrssBuf)-1]
tbfw.addrssBufs[workerID] = addrssBuf
addrs.addrs = addrs.addrsPrealloc[:0]
return addrs
} }
func newTmpBlocksFileWrapper(sns []*storageNode) *tmpBlocksFileWrapper { func newTmpBlocksFileWrapper(sns []*storageNode) *tmpBlocksFileWrapper {
@ -1384,6 +1395,7 @@ func newTmpBlocksFileWrapper(sns []*storageNode) *tmpBlocksFileWrapper {
ms: ms, ms: ms,
orderedMetricNamess: make([][]string, n), orderedMetricNamess: make([][]string, n),
metricNamesBufs: make([][]byte, n), metricNamesBufs: make([][]byte, n),
addrssBufs: make([][]blockAddrs, n),
} }
} }
@ -1399,7 +1411,7 @@ func (tbfw *tmpBlocksFileWrapper) RegisterAndWriteBlock(mb *storage.MetricBlock,
m := tbfw.ms[workerID] m := tbfw.ms[workerID]
addrs := m[string(metricName)] addrs := m[string(metricName)]
if addrs == nil { if addrs == nil {
addrs = newBlockAddrs() addrs = tbfw.newBlockAddrs(workerID)
} }
addrs.addrs = append(addrs.addrs, addr) addrs.addrs = append(addrs.addrs, addr)
if len(addrs.addrs) == 1 { if len(addrs.addrs) == 1 {
@ -1434,7 +1446,7 @@ func (tbfw *tmpBlocksFileWrapper) Finalize() ([]string, map[string]*blockAddrs,
dstAddrs, ok := addrsByMetricName[metricName] dstAddrs, ok := addrsByMetricName[metricName]
if !ok { if !ok {
orderedMetricNames = append(orderedMetricNames, metricName) orderedMetricNames = append(orderedMetricNames, metricName)
dstAddrs = newBlockAddrs() dstAddrs = tbfw.newBlockAddrs(uint(i))
addrsByMetricName[metricName] = dstAddrs addrsByMetricName[metricName] = dstAddrs
} }
dstAddrs.addrs = append(dstAddrs.addrs, m[metricName].addrs...) dstAddrs.addrs = append(dstAddrs.addrs, m[metricName].addrs...)