[#8] hrw: Do not create index slice for sorter
`ind` is only needed to index dist or weights, swap them directly. ``` goos: linux goarch: amd64 pkg: git.frostfs.info/TrueCloudLab/hrw cpu: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz │ 0 │ 1 │ │ sec/op │ sec/op vs base │ SortHashersByValue_Typed_fnv_10-8 596.2n ± 4% 580.1n ± 1% -2.72% (p=0.000 n=10) SortHashersByValue_Typed_fnv_100-8 4.453µ ± 2% 4.215µ ± 2% -5.35% (p=0.000 n=10) SortHashersByValue_Typed_fnv_1000-8 41.58µ ± 4% 39.40µ ± 1% -5.23% (p=0.000 n=10) SortHashersByWeightValueTyped_fnv_10-8 624.5n ± 2% 599.6n ± 2% -3.99% (p=0.000 n=10) SortHashersByWeightValueTyped_fnv_100-8 4.593µ ± 2% 4.337µ ± 5% -5.56% (p=0.003 n=10) SortHashersByWeightValueTyped_fnv_1000-8 4.896µ ± 8% 4.344µ ± 3% -11.27% (p=0.000 n=10) geomean 4.668µ 4.400µ -5.75% │ 0 │ 1 │ │ B/op │ B/op vs base │ SortHashersByValue_Typed_fnv_10-8 584.0 ± 0% 472.0 ± 0% -19.18% (p=0.000 n=10) SortHashersByValue_Typed_fnv_100-8 4.367Ki ± 0% 3.461Ki ± 0% -20.75% (p=0.000 n=10) SortHashersByValue_Typed_fnv_1000-8 39.80Ki ± 0% 31.77Ki ± 0% -20.18% (p=0.000 n=10) SortHashersByWeightValueTyped_fnv_10-8 600.0 ± 0% 472.0 ± 0% -21.33% (p=0.000 n=10) SortHashersByWeightValueTyped_fnv_100-8 4.383Ki ± 0% 3.461Ki ± 0% -21.03% (p=0.000 n=10) SortHashersByWeightValueTyped_fnv_1000-8 4.383Ki ± 0% 3.461Ki ± 0% -21.03% (p=0.000 n=10) geomean 3.742Ki 3.070Ki -17.96% │ 0 │ 1 │ │ allocs/op │ allocs/op vs base │ SortHashersByValue_Typed_fnv_10-8 17.00 ± 0% 16.00 ± 0% -5.88% (p=0.000 n=10) SortHashersByValue_Typed_fnv_100-8 107.0 ± 0% 106.0 ± 0% -0.93% (p=0.000 n=10) SortHashersByValue_Typed_fnv_1000-8 1.007k ± 0% 1.006k ± 0% -0.10% (p=0.000 n=10) SortHashersByWeightValueTyped_fnv_10-8 17.00 ± 0% 16.00 ± 0% -5.88% (p=0.000 n=10) SortHashersByWeightValueTyped_fnv_100-8 107.0 ± 0% 106.0 ± 0% -0.93% (p=0.000 n=10) SortHashersByWeightValueTyped_fnv_1000-8 107.0 ± 0% 106.0 ± 0% -0.93% (p=0.000 n=10) geomean 115.3 113.0 -1.94% ``` Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
parent
2c085708de
commit
c175ef4099
1 changed files with 29 additions and 27 deletions
56
hrw.go
56
hrw.go
|
@ -243,24 +243,6 @@ func ValidateWeights(weights []float64) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSorter(l int, byIndex bool, nodes []uint64, h uint64,
|
|
||||||
swap func(i, j int)) (*sorter, []int, []uint64) {
|
|
||||||
ind := make([]int, l)
|
|
||||||
dist := make([]uint64, l)
|
|
||||||
for i := 0; i < l; i++ {
|
|
||||||
ind[i] = i
|
|
||||||
dist[i] = getDistance(byIndex, i, nodes, h)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &sorter{
|
|
||||||
l: l,
|
|
||||||
swap: func(i, j int) {
|
|
||||||
swap(i, j)
|
|
||||||
ind[i], ind[j] = ind[j], ind[i]
|
|
||||||
},
|
|
||||||
}, ind, dist
|
|
||||||
}
|
|
||||||
|
|
||||||
// sortByWeight sorts nodes by weight using provided swapper.
|
// sortByWeight sorts nodes by weight using provided swapper.
|
||||||
// nodes contains hrw hashes. If it is nil, indices are used.
|
// nodes contains hrw hashes. If it is nil, indices are used.
|
||||||
func sortByWeight(l int, byIndex bool, nodes []uint64, weights []float64, hash uint64, swap func(i, j int)) {
|
func sortByWeight(l int, byIndex bool, nodes []uint64, weights []float64, hash uint64, swap func(i, j int)) {
|
||||||
|
@ -270,14 +252,23 @@ func sortByWeight(l int, byIndex bool, nodes []uint64, weights []float64, hash u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s, ind, dist := newSorter(l, byIndex, nodes, hash, swap)
|
dist := make([]float64, l)
|
||||||
s.less = func(i, j int) bool {
|
for i := 0; i < l; i++ {
|
||||||
ii, jj := ind[i], ind[j]
|
d := getDistance(byIndex, i, nodes, hash)
|
||||||
// `maxUint64 - distance` makes the shorter distance more valuable
|
// `maxUint64 - distance` makes the shorter distance more valuable
|
||||||
// it is necessary for operation with normalized values
|
// it is necessary for operation with normalized values
|
||||||
wi := float64(^uint64(0)-dist[ii]) * weights[ii]
|
dist[i] = float64(^uint64(0)-d) * weights[i]
|
||||||
wj := float64(^uint64(0)-dist[jj]) * weights[jj]
|
}
|
||||||
return wi > wj // higher distance must be placed lower to be first
|
|
||||||
|
s := &sorter{
|
||||||
|
l: l,
|
||||||
|
swap: func(i, j int) {
|
||||||
|
swap(i, j)
|
||||||
|
dist[i], dist[j] = dist[j], dist[i]
|
||||||
|
},
|
||||||
|
less: func(i, j int) bool {
|
||||||
|
return dist[i] > dist[j] // higher distance must be placed lower to be first
|
||||||
|
},
|
||||||
}
|
}
|
||||||
sort.Sort(s)
|
sort.Sort(s)
|
||||||
}
|
}
|
||||||
|
@ -285,9 +276,20 @@ func sortByWeight(l int, byIndex bool, nodes []uint64, weights []float64, hash u
|
||||||
// sortByDistance sorts nodes by hrw distance using provided swapper.
|
// sortByDistance sorts nodes by hrw distance using provided swapper.
|
||||||
// nodes contains hrw hashes. If it is nil, indices are used.
|
// nodes contains hrw hashes. If it is nil, indices are used.
|
||||||
func sortByDistance(l int, byIndex bool, nodes []uint64, hash uint64, swap func(i, j int)) {
|
func sortByDistance(l int, byIndex bool, nodes []uint64, hash uint64, swap func(i, j int)) {
|
||||||
s, ind, dist := newSorter(l, byIndex, nodes, hash, swap)
|
dist := make([]uint64, l)
|
||||||
s.less = func(i, j int) bool {
|
for i := 0; i < l; i++ {
|
||||||
return dist[ind[i]] < dist[ind[j]]
|
dist[i] = getDistance(byIndex, i, nodes, hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
s := &sorter{
|
||||||
|
l: l,
|
||||||
|
swap: func(i, j int) {
|
||||||
|
swap(i, j)
|
||||||
|
dist[i], dist[j] = dist[j], dist[i]
|
||||||
|
},
|
||||||
|
less: func(i, j int) bool {
|
||||||
|
return dist[i] < dist[j]
|
||||||
|
},
|
||||||
}
|
}
|
||||||
sort.Sort(s)
|
sort.Sort(s)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue