From a1a308bd7ed914367eb24f884ecffff88d608555 Mon Sep 17 00:00:00 2001 From: tsthght <781181214@qq.com> Date: Wed, 18 Sep 2019 21:59:46 +0800 Subject: [PATCH] expression: implement vectorized evaluation for builtinPowSig (#12242) --- expression/bench_test.go | 19 +++++++++++++++ expression/builtin_math_vec.go | 36 +++++++++++++++++++++++++++++ expression/builtin_math_vec_test.go | 3 +++ 3 files changed, 58 insertions(+) diff --git a/expression/bench_test.go b/expression/bench_test.go index abd3eb5adb7b6..e36c43be1c742 100644 --- a/expression/bench_test.go +++ b/expression/bench_test.go @@ -248,6 +248,25 @@ func (g *defaultGener) gen() interface{} { return nil } +// rangeRealGener is used to generate float64 items in [begin, end]. +type rangeRealGener struct { + begin float64 + end float64 + + nullRation float64 +} + +func (g *rangeRealGener) gen() interface{} { + if rand.Float64() < g.nullRation { + return nil + } + if g.end <= g.begin { + g.begin = -100 + g.end = 100 + } + return rand.Float64()*(g.end-g.begin) + g.begin +} + // rangeInt64Gener is used to generate int64 items in [begin, end). type rangeInt64Gener struct { begin int diff --git a/expression/builtin_math_vec.go b/expression/builtin_math_vec.go index f9cfcd715fc4f..e9a0c0feb1425 100644 --- a/expression/builtin_math_vec.go +++ b/expression/builtin_math_vec.go @@ -311,3 +311,39 @@ func (b *builtinRoundDecSig) vecEvalDecimal(input *chunk.Chunk, result *chunk.Co func (b *builtinRoundDecSig) vectorized() bool { return true } + +func (b *builtinPowSig) vecEvalReal(input *chunk.Chunk, result *chunk.Column) error { + n := input.NumRows() + buf1, err := b.bufAllocator.get(types.ETReal, n) + if err != nil { + return err + } + defer b.bufAllocator.put(buf1) + if err := b.args[0].VecEvalReal(b.ctx, input, buf1); err != nil { + return err + } + + if err := b.args[1].VecEvalReal(b.ctx, input, result); err != nil { + return err + } + + x := buf1.Float64s() + y := result.Float64s() + result.MergeNulls(buf1) + f64s := result.Float64s() + for i := 0; i < n; i++ { + if result.IsNull(i) { + continue + } + power := math.Pow(x[i], y[i]) + if math.IsInf(power, -1) || math.IsInf(power, 1) || math.IsNaN(power) { + return types.ErrOverflow.GenWithStackByArgs("DOUBLE", fmt.Sprintf("pow(%s, %s)", strconv.FormatFloat(x[i], 'f', -1, 64), strconv.FormatFloat(y[i], 'f', -1, 64))) + } + f64s[i] = power + } + return nil +} + +func (b *builtinPowSig) vectorized() bool { + return true +} diff --git a/expression/builtin_math_vec_test.go b/expression/builtin_math_vec_test.go index a2b90177f2f21..39151c58b41ea 100644 --- a/expression/builtin_math_vec_test.go +++ b/expression/builtin_math_vec_test.go @@ -61,6 +61,9 @@ var vecBuiltinMathCases = map[string][]vecExprBenchCase{ ast.Round: { {types.ETDecimal, []types.EvalType{types.ETDecimal}, nil}, }, + ast.Pow: { + {types.ETReal, []types.EvalType{types.ETReal, types.ETReal}, []dataGenerator{&rangeRealGener{0, 10, 0.5}, &rangeRealGener{0, 100, 0.5}}}, + }, } func (s *testEvaluatorSuite) TestVectorizedBuiltinMathEvalOneVec(c *C) {