mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
lib/decimal: follow-up for e6bad5174f
- Add a benchmark for CalbirateAndScale. - Reduce the decimal multipliers table size from 256Kb to 192bytes. - Use more clear naming for variables. Updates https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5672
This commit is contained in:
parent
64780f4f02
commit
0ed291102d
2 changed files with 50 additions and 22 deletions
|
@ -7,20 +7,6 @@ import (
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/fastnum"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/fastnum"
|
||||||
)
|
)
|
||||||
|
|
||||||
const tableLen = 32767
|
|
||||||
|
|
||||||
var table = func() []int64 {
|
|
||||||
out := make([]int64, 0, tableLen)
|
|
||||||
var cur int64 = 10
|
|
||||||
for i := 1; i <= tableLen; i++ {
|
|
||||||
out = append(out, cur)
|
|
||||||
if cur*10 > 0 {
|
|
||||||
cur *= 10
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}()
|
|
||||||
|
|
||||||
// CalibrateScale calibrates a and b with the corresponding exponents ae, be
|
// CalibrateScale calibrates a and b with the corresponding exponents ae, be
|
||||||
// and returns the resulting exponent e.
|
// and returns the resulting exponent e.
|
||||||
func CalibrateScale(a []int64, ae int16, b []int64, be int16) (e int16) {
|
func CalibrateScale(a []int64, ae int16, b []int64, be int16) (e int16) {
|
||||||
|
@ -49,29 +35,49 @@ func CalibrateScale(a []int64, ae int16, b []int64, be int16) (e int16) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
upExp -= downExp
|
upExp -= downExp
|
||||||
|
|
||||||
if upExp > 0 {
|
if upExp > 0 {
|
||||||
times := table[upExp-1]
|
m := getDecimalMultiplier(uint16(upExp))
|
||||||
for i, v := range a {
|
for i, v := range a {
|
||||||
if isSpecialValue(v) {
|
if isSpecialValue(v) {
|
||||||
// Do not take into account special values.
|
// Do not take into account special values.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
a[i] = v * times
|
a[i] = v * m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if downExp > 0 {
|
if downExp > 0 {
|
||||||
times := table[downExp-1]
|
if downExp > 18 {
|
||||||
for i, v := range b {
|
for i, v := range b {
|
||||||
if isSpecialValue(v) {
|
if isSpecialValue(v) {
|
||||||
// Do not take into account special values.
|
// Do not take into account special values.
|
||||||
continue
|
continue
|
||||||
|
}
|
||||||
|
b[i] = 0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m := getDecimalMultiplier(uint16(downExp))
|
||||||
|
for i, v := range b {
|
||||||
|
if isSpecialValue(v) {
|
||||||
|
// Do not take into account special values.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
b[i] = v / m
|
||||||
}
|
}
|
||||||
b[i] = v / times
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return be + downExp
|
return be + downExp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getDecimalMultiplier(exp uint16) int64 {
|
||||||
|
if exp >= uint16(len(decimalMultipliers)) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return decimalMultipliers[exp]
|
||||||
|
}
|
||||||
|
|
||||||
|
var decimalMultipliers = []int64{1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18}
|
||||||
|
|
||||||
// ExtendFloat64sCapacity extends dst capacity to hold additionalItems
|
// ExtendFloat64sCapacity extends dst capacity to hold additionalItems
|
||||||
// and returns the extended dst.
|
// and returns the extended dst.
|
||||||
func ExtendFloat64sCapacity(dst []float64, additionalItems int) []float64 {
|
func ExtendFloat64sCapacity(dst []float64, additionalItems int) []float64 {
|
||||||
|
|
|
@ -7,6 +7,28 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func BenchmarkCalbirateScale(b *testing.B) {
|
||||||
|
aSrc := []int64{1, 2, 3, 4, 5, 67, 8, 9, 12, 324, 29, -34, -94, -84, -34, 0, 2, 3}
|
||||||
|
bSrc := []int64{2, 3, 4, 5, 67, 8, 9, 12, 324, 29, -34, -94, -84, -34, 0, 2, 3, 1}
|
||||||
|
const aScale = 1
|
||||||
|
const bScale = 2
|
||||||
|
const scaleExpected = 1
|
||||||
|
|
||||||
|
b.ReportAllocs()
|
||||||
|
b.SetBytes(int64(len(aSrc)))
|
||||||
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
|
var a, b []int64
|
||||||
|
for pb.Next() {
|
||||||
|
a = append(a[:0], aSrc...)
|
||||||
|
b = append(b[:0], bSrc...)
|
||||||
|
scale := CalibrateScale(a, aScale, b, bScale)
|
||||||
|
if scale != scaleExpected {
|
||||||
|
panic(fmt.Errorf("unexpected scale; got %d; want %d", scale, scaleExpected))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkAppendDecimalToFloat(b *testing.B) {
|
func BenchmarkAppendDecimalToFloat(b *testing.B) {
|
||||||
b.Run("RealFloat", func(b *testing.B) {
|
b.Run("RealFloat", func(b *testing.B) {
|
||||||
benchmarkAppendDecimalToFloat(b, testVA, vaScale)
|
benchmarkAppendDecimalToFloat(b, testVA, vaScale)
|
||||||
|
|
Loading…
Reference in a new issue