Skip to content

Commit

Permalink
expression: modify the test framework for vectorized expression evalu…
Browse files Browse the repository at this point in the history
…ation functions (#12115)
  • Loading branch information
Reminiscent authored and qw4990 committed Sep 10, 2019
1 parent d5626a9 commit add1023
Show file tree
Hide file tree
Showing 8 changed files with 277 additions and 46 deletions.
42 changes: 17 additions & 25 deletions expression/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,23 +289,7 @@ type vecExprBenchCase struct {
geners []dataGenerator
}

var vecExprBenchCases = map[string][]vecExprBenchCase{
ast.Cast: {
{types.ETInt, []types.EvalType{types.ETInt}, nil},
},
ast.Repeat: {
{types.ETString, []types.EvalType{types.ETString, types.ETInt}, []dataGenerator{&randLenStrGener{10, 20}, &rangeInt64Gener{-10, 10}}},
},
ast.Log10: {
{types.ETReal, []types.EvalType{types.ETReal}, nil},
},
ast.If: {
{types.ETJson, []types.EvalType{types.ETInt, types.ETJson, types.ETJson}, nil},
},
ast.Greatest: {
{types.ETDecimal, []types.EvalType{types.ETDecimal, types.ETDecimal, types.ETDecimal}, nil},
},
}
type vecExprBenchCases map[string][]vecExprBenchCase

func fillColumn(eType types.EvalType, chk *chunk.Chunk, colIdx int, testCase vecExprBenchCase) {
batchSize := 1024
Expand Down Expand Up @@ -385,9 +369,11 @@ func genVecExprBenchCase(ctx sessionctx.Context, funcName string, testCase vecEx
return expr, input, output
}

func (s *testEvaluatorSuite) TestVectorizedEvalOneVec(c *C) {
// testVectorizedEvalOneVec is used to verify that the special vectorized
// expression is evaluated correctly during projection
func testVectorizedEvalOneVec(c *C, vecExprCases vecExprBenchCases) {
ctx := mock.NewContext()
for funcName, testCases := range vecExprBenchCases {
for funcName, testCases := range vecExprCases {
for _, testCase := range testCases {
expr, input, output := genVecExprBenchCase(ctx, funcName, testCase)
output2 := output.CopyConstruct()
Expand Down Expand Up @@ -430,9 +416,11 @@ func (s *testEvaluatorSuite) TestVectorizedEvalOneVec(c *C) {
}
}

func BenchmarkVectorizedEvalOneVec(b *testing.B) {
// benchmarkVectorizedEvalOneVec is used to get the effect of
// using the special vectorized expression evaluations during projection
func benchmarkVectorizedEvalOneVec(b *testing.B, vecExprCases vecExprBenchCases) {
ctx := mock.NewContext()
for funcName, testCases := range vecExprBenchCases {
for funcName, testCases := range vecExprCases {
for _, testCase := range testCases {
expr, input, output := genVecExprBenchCase(ctx, funcName, testCase)
exprName := expr.String()
Expand Down Expand Up @@ -507,8 +495,10 @@ func genVecBuiltinFuncBenchCase(ctx sessionctx.Context, funcName string, testCas
return baseFunc, input, result
}

func (s *testEvaluatorSuite) TestVectorizedBuiltinFunc(c *C) {
for funcName, testCases := range vecExprBenchCases {
// testVectorizedBuiltinFunc is used to verify that the special vectorized
// expression is evaluated correctly
func testVectorizedBuiltinFunc(c *C, vecExprCases vecExprBenchCases) {
for funcName, testCases := range vecExprCases {
for _, testCase := range testCases {
ctx := mock.NewContext()
baseFunc, input, output := genVecBuiltinFuncBenchCase(ctx, funcName, testCase)
Expand Down Expand Up @@ -629,9 +619,11 @@ func (s *testEvaluatorSuite) TestVectorizedBuiltinFunc(c *C) {
}
}

func BenchmarkVectorizedBuiltinFunc(b *testing.B) {
// benchmarkVectorizedBuiltinFunc is used to get the effect of
// using the special vectorized expression evaluations
func benchmarkVectorizedBuiltinFunc(b *testing.B, vecExprCases vecExprBenchCases) {
ctx := mock.NewContext()
for funcName, testCases := range vecExprBenchCases {
for funcName, testCases := range vecExprCases {
for _, testCase := range testCases {
baseFunc, input, output := genVecBuiltinFuncBenchCase(ctx, funcName, testCase)
baseFuncName := fmt.Sprintf("%v", reflect.TypeOf(baseFunc))
Expand Down
21 changes: 0 additions & 21 deletions expression/builtin_cast.go
Original file line number Diff line number Diff line change
Expand Up @@ -435,10 +435,6 @@ func (b *builtinCastIntAsIntSig) Clone() builtinFunc {
return newSig
}

func (b *builtinCastIntAsIntSig) vectorized() bool {
return true
}

func (b *builtinCastIntAsIntSig) evalInt(row chunk.Row) (res int64, isNull bool, err error) {
res, isNull, err = b.args[0].EvalInt(b.ctx, row)
if isNull || err != nil {
Expand All @@ -450,23 +446,6 @@ func (b *builtinCastIntAsIntSig) evalInt(row chunk.Row) (res int64, isNull bool,
return
}

func (b *builtinCastIntAsIntSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error {
if err := b.args[0].VecEvalInt(b.ctx, input, result); err != nil {
return err
}
if b.inUnion && mysql.HasUnsignedFlag(b.tp.Flag) {
i64s := result.Int64s()
// the null array of result is set by its child args[0],
// so we can skip it here to make this loop simpler to improve its performance.
for i := range i64s {
if i64s[i] < 0 {
i64s[i] = 0
}
}
}
return nil
}

type builtinCastIntAsRealSig struct {
baseBuiltinCastFunc
}
Expand Down
40 changes: 40 additions & 0 deletions expression/builtin_cast_vec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright 2019 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package expression

import (
"github.com/pingcap/parser/mysql"
"github.com/pingcap/tidb/util/chunk"
)

func (b *builtinCastIntAsIntSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error {
if err := b.args[0].VecEvalInt(b.ctx, input, result); err != nil {
return err
}
if b.inUnion && mysql.HasUnsignedFlag(b.tp.Flag) {
i64s := result.Int64s()
// the null array of result is set by its child args[0],
// so we can skip it here to make this loop simpler to improve its performance.
for i := range i64s {
if i64s[i] < 0 {
i64s[i] = 0
}
}
}
return nil
}

func (b *builtinCastIntAsIntSig) vectorized() bool {
return true
}
44 changes: 44 additions & 0 deletions expression/builtin_cast_vec_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2019 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package expression

import (
"testing"

. "github.com/pingcap/check"
"github.com/pingcap/parser/ast"
"github.com/pingcap/tidb/types"
)

var vecBuiltinCastCases = map[string][]vecExprBenchCase{
ast.Cast: {
{types.ETInt, []types.EvalType{types.ETInt}, nil},
},
}

func (s *testEvaluatorSuite) TestVectorizedBuiltinCastEvalOneVec(c *C) {
testVectorizedEvalOneVec(c, vecBuiltinCastCases)
}

func (s *testEvaluatorSuite) TestVectorizedBuiltinCastFunc(c *C) {
testVectorizedBuiltinFunc(c, vecBuiltinCastCases)
}

func BenchmarkVectorizedBuiltinCastEvalOneVec(b *testing.B) {
benchmarkVectorizedEvalOneVec(b, vecBuiltinCastCases)
}

func BenchmarkVectorizedBuiltinCastFunc(b *testing.B) {
benchmarkVectorizedBuiltinFunc(b, vecBuiltinCastCases)
}
44 changes: 44 additions & 0 deletions expression/builtin_compare_vec_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2019 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package expression

import (
"testing"

. "github.com/pingcap/check"
"github.com/pingcap/parser/ast"
"github.com/pingcap/tidb/types"
)

var vecBuiltinCompareCases = map[string][]vecExprBenchCase{
ast.Greatest: {
{types.ETDecimal, []types.EvalType{types.ETDecimal, types.ETDecimal, types.ETDecimal}, nil},
},
}

func (s *testEvaluatorSuite) TestVectorizedBuiltinCompareEvalOneVec(c *C) {
testVectorizedEvalOneVec(c, vecBuiltinCompareCases)
}

func (s *testEvaluatorSuite) TestVectorizedBuiltinCompareFunc(c *C) {
testVectorizedBuiltinFunc(c, vecBuiltinCompareCases)
}

func BenchmarkVectorizedBuiltinCompareEvalOneVec(b *testing.B) {
benchmarkVectorizedEvalOneVec(b, vecBuiltinCompareCases)
}

func BenchmarkVectorizedBuiltinCompareFunc(b *testing.B) {
benchmarkVectorizedBuiltinFunc(b, vecBuiltinCompareCases)
}
44 changes: 44 additions & 0 deletions expression/builtin_control_vec_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2019 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package expression

import (
"testing"

. "github.com/pingcap/check"
"github.com/pingcap/parser/ast"
"github.com/pingcap/tidb/types"
)

var vecBuiltinControlCases = map[string][]vecExprBenchCase{
ast.If: {
{types.ETJson, []types.EvalType{types.ETInt, types.ETJson, types.ETJson}, nil},
},
}

func (s *testEvaluatorSuite) TestVectorizedBuiltinControlEvalOneVec(c *C) {
testVectorizedEvalOneVec(c, vecBuiltinControlCases)
}

func (s *testEvaluatorSuite) TestVectorizedBuiltinControlFunc(c *C) {
testVectorizedBuiltinFunc(c, vecBuiltinControlCases)
}

func BenchmarkVectorizedBuiltinControlEvalOneVec(b *testing.B) {
benchmarkVectorizedEvalOneVec(b, vecBuiltinControlCases)
}

func BenchmarkVectorizedBuiltinControlFunc(b *testing.B) {
benchmarkVectorizedBuiltinFunc(b, vecBuiltinControlCases)
}
44 changes: 44 additions & 0 deletions expression/builtin_math_vec_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2019 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package expression

import (
"testing"

. "github.com/pingcap/check"
"github.com/pingcap/parser/ast"
"github.com/pingcap/tidb/types"
)

var vecBuiltinMathCases = map[string][]vecExprBenchCase{
ast.Log10: {
{types.ETReal, []types.EvalType{types.ETReal}, nil},
},
}

func (s *testEvaluatorSuite) TestVectorizedBuiltinMathEvalOneVec(c *C) {
testVectorizedEvalOneVec(c, vecBuiltinMathCases)
}

func (s *testEvaluatorSuite) TestVectorizedBuiltinMathFunc(c *C) {
testVectorizedBuiltinFunc(c, vecBuiltinMathCases)
}

func BenchmarkVectorizedBuiltinMathEvalOneVec(b *testing.B) {
benchmarkVectorizedEvalOneVec(b, vecBuiltinMathCases)
}

func BenchmarkVectorizedBuiltinMathFunc(b *testing.B) {
benchmarkVectorizedBuiltinFunc(b, vecBuiltinMathCases)
}
44 changes: 44 additions & 0 deletions expression/builtin_string_vec_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2019 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package expression

import (
"testing"

. "github.com/pingcap/check"
"github.com/pingcap/parser/ast"
"github.com/pingcap/tidb/types"
)

var vecBuiltinStringCases = map[string][]vecExprBenchCase{
ast.Repeat: {
{types.ETString, []types.EvalType{types.ETString, types.ETInt}, []dataGenerator{&randLenStrGener{10, 20}, &rangeInt64Gener{-10, 10}}},
},
}

func (s *testEvaluatorSuite) TestVectorizedBuiltinStringEvalOneVec(c *C) {
testVectorizedEvalOneVec(c, vecBuiltinStringCases)
}

func (s *testEvaluatorSuite) TestVectorizedBuiltinStringFunc(c *C) {
testVectorizedBuiltinFunc(c, vecBuiltinStringCases)
}

func BenchmarkVectorizedBuiltinStringEvalOneVec(b *testing.B) {
benchmarkVectorizedEvalOneVec(b, vecBuiltinStringCases)
}

func BenchmarkVectorizedBuiltinStringFunc(b *testing.B) {
benchmarkVectorizedBuiltinFunc(b, vecBuiltinStringCases)
}

0 comments on commit add1023

Please sign in to comment.