From db9104534802fc937fb028c3320bc1204c111799 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Tue, 8 Sep 2020 14:00:47 +0300 Subject: [PATCH] app/vmselect/promql: increase floating point calculations accuracy by dividing by `1e3` instead of multiplying by `1e-3` --- app/vmselect/promql/eval.go | 2 +- app/vmselect/promql/exec_test.go | 4 ++-- app/vmselect/promql/rollup.go | 30 +++++++++++++++--------------- app/vmselect/promql/rollup_test.go | 10 +++++----- app/vmselect/promql/transform.go | 6 +++--- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/app/vmselect/promql/eval.go b/app/vmselect/promql/eval.go index d411e785aa..f6f246256e 100644 --- a/app/vmselect/promql/eval.go +++ b/app/vmselect/promql/eval.go @@ -851,7 +851,7 @@ func evalTime(ec *EvalConfig) []*timeseries { timestamps := rv[0].Timestamps values := rv[0].Values for i, ts := range timestamps { - values[i] = float64(ts) * 1e-3 + values[i] = float64(ts) / 1e3 } return rv } diff --git a/app/vmselect/promql/exec_test.go b/app/vmselect/promql/exec_test.go index 2158a91c6f..f05b043ace 100644 --- a/app/vmselect/promql/exec_test.go +++ b/app/vmselect/promql/exec_test.go @@ -4833,10 +4833,10 @@ func TestExecSuccess(t *testing.T) { }) t.Run(`integrate(time())`, func(t *testing.T) { t.Parallel() - q := `integrate(time()*1e-3)` + q := `integrate(time()/1e3)` r := netstorage.Result{ MetricName: metricNameExpected, - Values: []float64{180, 220.00000000000003, 260, 300, 340.00000000000006, 380}, + Values: []float64{180, 220.00000000000003, 259.99999999999994, 300, 340.00000000000006, 380}, Timestamps: timestampsExpected, } resultExpected := []netstorage.Result{r} diff --git a/app/vmselect/promql/rollup.go b/app/vmselect/promql/rollup.go index 77f8792a70..a271757b18 100644 --- a/app/vmselect/promql/rollup.go +++ b/app/vmselect/promql/rollup.go @@ -670,7 +670,7 @@ func derivValues(values []float64, timestamps []int64) { values[i] = prevDeriv continue } - dt := float64(ts-prevTs) * 1e-3 + dt := float64(ts-prevTs) / 1e3 prevDeriv = (v - prevValue) / dt values[i] = prevDeriv prevValue = v @@ -790,7 +790,7 @@ func linearRegression(rfa *rollupFuncArg) (float64, float64) { n = 0 } for i, v := range values { - dt := float64(timestamps[i]-tFirst) * 1e-3 + dt := float64(timestamps[i]-tFirst) / 1e3 vSum += v tSum += dt tvSum += dt * v @@ -803,7 +803,7 @@ func linearRegression(rfa *rollupFuncArg) (float64, float64) { k := (n*tvSum - tSum*vSum) / (n*ttSum - tSum*tSum) v := (vSum - k*tSum) / n // Adjust v to the last timestamp on the given time range. - v += k * (float64(timestamps[len(timestamps)-1]-tFirst) * 1e-3) + v += k * (float64(timestamps[len(timestamps)-1]-tFirst) / 1e3) return v, k } @@ -1055,7 +1055,7 @@ func rollupTmin(rfa *rollupFuncArg) float64 { minTimestamp = timestamps[i] } } - return float64(minTimestamp) * 1e-3 + return float64(minTimestamp) / 1e3 } func rollupTmax(rfa *rollupFuncArg) float64 { @@ -1074,7 +1074,7 @@ func rollupTmax(rfa *rollupFuncArg) float64 { maxTimestamp = timestamps[i] } } - return float64(maxTimestamp) * 1e-3 + return float64(maxTimestamp) / 1e3 } func rollupSum(rfa *rollupFuncArg) float64 { @@ -1303,7 +1303,7 @@ func rollupDerivFast(rfa *rollupFuncArg) float64 { vEnd := values[len(values)-1] tEnd := timestamps[len(timestamps)-1] dv := vEnd - prevValue - dt := float64(tEnd-prevTimestamp) * 1e-3 + dt := float64(tEnd-prevTimestamp) / 1e3 return dv / dt } @@ -1329,7 +1329,7 @@ func rollupIderiv(rfa *rollupFuncArg) float64 { // So just return nan return nan } - return (values[0] - rfa.prevValue) / (float64(timestamps[0]-rfa.prevTimestamp) * 1e-3) + return (values[0] - rfa.prevValue) / (float64(timestamps[0]-rfa.prevTimestamp) / 1e3) } vEnd := values[len(values)-1] tEnd := timestamps[len(timestamps)-1] @@ -1353,7 +1353,7 @@ func rollupIderiv(rfa *rollupFuncArg) float64 { } dv := vEnd - vStart dt := tEnd - tStart - return dv / (float64(dt) * 1e-3) + return dv / (float64(dt) / 1e3) } func rollupLifetime(rfa *rollupFuncArg) float64 { @@ -1363,12 +1363,12 @@ func rollupLifetime(rfa *rollupFuncArg) float64 { if len(timestamps) < 2 { return nan } - return float64(timestamps[len(timestamps)-1]-timestamps[0]) * 1e-3 + return float64(timestamps[len(timestamps)-1]-timestamps[0]) / 1e3 } if len(timestamps) == 0 { return nan } - return float64(timestamps[len(timestamps)-1]-rfa.prevTimestamp) * 1e-3 + return float64(timestamps[len(timestamps)-1]-rfa.prevTimestamp) / 1e3 } func rollupLag(rfa *rollupFuncArg) float64 { @@ -1378,9 +1378,9 @@ func rollupLag(rfa *rollupFuncArg) float64 { if math.IsNaN(rfa.prevValue) { return nan } - return float64(rfa.currTimestamp-rfa.prevTimestamp) * 1e-3 + return float64(rfa.currTimestamp-rfa.prevTimestamp) / 1e3 } - return float64(rfa.currTimestamp-timestamps[len(timestamps)-1]) * 1e-3 + return float64(rfa.currTimestamp-timestamps[len(timestamps)-1]) / 1e3 } func rollupScrapeInterval(rfa *rollupFuncArg) float64 { @@ -1390,12 +1390,12 @@ func rollupScrapeInterval(rfa *rollupFuncArg) float64 { if len(timestamps) < 2 { return nan } - return float64(timestamps[len(timestamps)-1]-timestamps[0]) * 1e-3 / float64(len(timestamps)-1) + return (float64(timestamps[len(timestamps)-1]-timestamps[0]) / 1e3) / float64(len(timestamps)-1) } if len(timestamps) == 0 { return nan } - return (float64(timestamps[len(timestamps)-1]-rfa.prevTimestamp) * 1e-3) / float64(len(timestamps)) + return (float64(timestamps[len(timestamps)-1]-rfa.prevTimestamp) / 1e3) / float64(len(timestamps)) } func rollupChanges(rfa *rollupFuncArg) float64 { @@ -1709,7 +1709,7 @@ func rollupIntegrate(rfa *rollupFuncArg) float64 { var sum float64 for i, v := range values { timestamp := timestamps[i] - dt := float64(timestamp-prevTimestamp) * 1e-3 + dt := float64(timestamp-prevTimestamp) / 1e3 sum += 0.5 * (v + prevValue) * dt prevTimestamp = timestamp prevValue = v diff --git a/app/vmselect/promql/rollup_test.go b/app/vmselect/promql/rollup_test.go index 4bb596a2e2..d8080685a8 100644 --- a/app/vmselect/promql/rollup_test.go +++ b/app/vmselect/promql/rollup_test.go @@ -139,16 +139,16 @@ func TestDerivValues(t *testing.T) { values = append([]float64{}, testValues...) derivValues(values, testTimestamps) - valuesExpected = []float64{-8900, 1111.111111111111, -1916.6666666666665, 2538.461538461538, -1818.1818181818182, 3611.111111111111, - -43500, 1882.3529411764705, -666.6666666666666, 400, 0, 0} + valuesExpected = []float64{-8900, 1111.111111111111, -1916.6666666666665, 2538.4615384615386, -1818.1818181818182, 3611.1111111111113, + -43500, 1882.3529411764705, -666.6666666666667, 400, 0, 0} testRowsEqual(t, values, testTimestamps, valuesExpected, testTimestamps) // remove counter resets values = append([]float64{}, testValues...) removeCounterResets(values) derivValues(values, testTimestamps) - valuesExpected = []float64{3400, 1111.111111111111, 1750, 2538.461538461538, 3090.909090909091, 3611.111111111111, - 6000, 1882.3529411764705, 1777.7777777777776, 400, 0, 0} + valuesExpected = []float64{3400, 1111.111111111111, 1750, 2538.4615384615386, 3090.909090909091, 3611.1111111111113, + 6000, 1882.3529411764705, 1777.7777777777778, 400, 0, 0} testRowsEqual(t, values, testTimestamps, valuesExpected, testTimestamps) // duplicate timestamps @@ -914,7 +914,7 @@ func TestRollupFuncsNoWindow(t *testing.T) { } rc.Timestamps = getTimestamps(rc.Start, rc.End, rc.Step) values := rc.Do(nil, testValues, testTimestamps) - valuesExpected := []float64{0, -2879.310344827587, 558.0608793686592, 422.84569138276544, 0} + valuesExpected := []float64{0, -2879.310344827587, 558.0608793686595, 422.84569138276544, 0} timestampsExpected := []int64{0, 40, 80, 120, 160} testRowsEqual(t, values, rc.Timestamps, valuesExpected, timestampsExpected) }) diff --git a/app/vmselect/promql/transform.go b/app/vmselect/promql/transform.go index 16ca9cc7f1..f900b51991 100644 --- a/app/vmselect/promql/transform.go +++ b/app/vmselect/promql/transform.go @@ -1674,15 +1674,15 @@ func newTransformFuncZeroArgs(f func(tfa *transformFuncArg) float64) transformFu } func transformStep(tfa *transformFuncArg) float64 { - return float64(tfa.ec.Step) * 1e-3 + return float64(tfa.ec.Step) / 1e3 } func transformStart(tfa *transformFuncArg) float64 { - return float64(tfa.ec.Start) * 1e-3 + return float64(tfa.ec.Start) / 1e3 } func transformEnd(tfa *transformFuncArg) float64 { - return float64(tfa.ec.End) * 1e-3 + return float64(tfa.ec.End) / 1e3 } // copyTimeseriesMetricNames returns a copy of tss with real copy of MetricNames,