From 1ac947af440b92fa9ba7d5a4e427ba1a2bf1271c Mon Sep 17 00:00:00 2001
From: Evgenii Stratonikov <e.stratonikov@yadro.com>
Date: Fri, 12 Jul 2024 10:46:53 +0300
Subject: [PATCH] [#236] netmap: Reuse slice for weights in ContainerNodes()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

```
goos: linux
goarch: amd64
pkg: git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap
cpu: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz
                                                              │    alloc     │               weights               │
                                                              │    sec/op    │    sec/op     vs base               │
Netmap_ContainerNodes/REP_2-8                                   8.677µ ±  6%   8.384µ ± 10%       ~ (p=0.247 n=10)
Netmap_ContainerNodes/REP_2_IN_X_CBF_2_SELECT_2_FROM_*_AS_X-8   7.946µ ± 14%   7.998µ ±  6%       ~ (p=0.481 n=10)
geomean                                                         8.303µ         8.189µ        -1.38%

                                                              │    alloc     │               weights               │
                                                              │     B/op     │     B/op      vs base               │
Netmap_ContainerNodes/REP_2-8                                   7.734Ki ± 0%   7.617Ki ± 0%  -1.52% (p=0.000 n=10)
Netmap_ContainerNodes/REP_2_IN_X_CBF_2_SELECT_2_FROM_*_AS_X-8   7.156Ki ± 0%   7.039Ki ± 0%  -1.64% (p=0.000 n=10)
geomean                                                         7.440Ki        7.322Ki       -1.58%

                                                              │   alloc    │              weights               │
                                                              │ allocs/op  │ allocs/op   vs base                │
Netmap_ContainerNodes/REP_2-8                                   92.00 ± 0%   77.00 ± 0%  -16.30% (p=0.000 n=10)
Netmap_ContainerNodes/REP_2_IN_X_CBF_2_SELECT_2_FROM_*_AS_X-8   92.00 ± 0%   77.00 ± 0%  -16.30% (p=0.000 n=10)
geomean                                                         92.00        77.00       -16.30%
```

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
---
 netmap/netmap.go   | 12 ++++++++----
 netmap/selector.go |  4 +++-
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/netmap/netmap.go b/netmap/netmap.go
index f0ece7d..85e2a84 100644
--- a/netmap/netmap.go
+++ b/netmap/netmap.go
@@ -113,9 +113,10 @@ func (n nodes) Hash() uint64 {
 	return 0
 }
 
-// weights returns slice of nodes weights W.
-func (n nodes) weights(wf weightFunc) []float64 {
-	w := make([]float64, 0, len(n))
+func (n nodes) appendWeightsTo(wf weightFunc, w []float64) []float64 {
+	if cap(w) < len(n) {
+		w = make([]float64, 0, len(n))
+	}
 	for i := range n {
 		w = append(w, wf(n[i]))
 	}
@@ -149,10 +150,13 @@ func (m NetMap) PlacementVectors(vectors [][]NodeInfo, pivot []byte) ([][]NodeIn
 	wf := defaultWeightFunc(m.nodes)
 	result := make([][]NodeInfo, len(vectors))
 
+	var ws []float64
+
 	for i := range vectors {
 		result[i] = make([]NodeInfo, len(vectors[i]))
 		copy(result[i], vectors[i])
-		hrw.SortHasherSliceByWeightValue(result[i], nodes(result[i]).weights(wf), h)
+		ws = nodes(result[i]).appendWeightsTo(wf, ws[:0])
+		hrw.SortHasherSliceByWeightValue(result[i], ws, h)
 	}
 
 	return result, nil
diff --git a/netmap/selector.go b/netmap/selector.go
index b16e774..ab73cec 100644
--- a/netmap/selector.go
+++ b/netmap/selector.go
@@ -171,8 +171,10 @@ func (c *context) getSelectionBase(s netmap.Selector) []nodeAttrPair {
 	}
 
 	if len(c.hrwSeed) != 0 {
+		var ws []float64
 		for i := range result {
-			hrw.SortHasherSliceByWeightValue(result[i].nodes, result[i].nodes.weights(c.weightFunc), c.hrwSeedHash)
+			ws = result[i].nodes.appendWeightsTo(c.weightFunc, ws[:0])
+			hrw.SortHasherSliceByWeightValue(result[i].nodes, ws, c.hrwSeedHash)
 		}
 	}