github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_vectorized_test.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package memex 15 16 import ( 17 "fmt" 18 "math/rand" 19 "sync" 20 "testing" 21 "time" 22 23 . "github.com/whtcorpsinc/check" 24 "github.com/whtcorpsinc/errors" 25 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 26 "github.com/whtcorpsinc/milevadb/types" 27 "github.com/whtcorpsinc/milevadb/types/json" 28 "github.com/whtcorpsinc/milevadb/soliton/chunk" 29 "github.com/whtcorpsinc/milevadb/soliton/mock" 30 ) 31 32 type mockVecPlusIntBuiltinFunc struct { 33 baseBuiltinFunc 34 35 buf *chunk.DeferredCauset 36 enableAlloc bool 37 } 38 39 func (p *mockVecPlusIntBuiltinFunc) allocBuf(n int) (*chunk.DeferredCauset, error) { 40 if p.enableAlloc { 41 return p.bufSlabPredictor.get(types.ETInt, n) 42 } 43 if p.buf == nil { 44 p.buf = chunk.NewDeferredCauset(types.NewFieldType(allegrosql.TypeLonglong), n) 45 } 46 return p.buf, nil 47 } 48 49 func (p *mockVecPlusIntBuiltinFunc) releaseBuf(buf *chunk.DeferredCauset) { 50 if p.enableAlloc { 51 p.bufSlabPredictor.put(buf) 52 } 53 } 54 55 func (p *mockVecPlusIntBuiltinFunc) vecEvalInt(input *chunk.Chunk, result *chunk.DeferredCauset) error { 56 n := input.NumRows() 57 buf, err := p.allocBuf(n) 58 if err != nil { 59 return err 60 } 61 defer p.releaseBuf(buf) 62 if err := p.args[0].VecEvalInt(p.ctx, input, result); err != nil { 63 return err 64 } 65 if err := p.args[1].VecEvalInt(p.ctx, input, buf); err != nil { 66 return err 67 } 68 dst64s := result.Int64s() 69 src64s := buf.Int64s() 70 for i := range dst64s { 71 dst64s[i] += src64s[i] 72 } 73 for i := 0; i < n; i++ { 74 if buf.IsNull(i) && !result.IsNull(i) { 75 result.SetNull(i, true) 76 } 77 } 78 return nil 79 } 80 81 func genMockVecPlusIntBuiltinFunc() (*mockVecPlusIntBuiltinFunc, *chunk.Chunk, *chunk.DeferredCauset) { 82 tp := types.NewFieldType(allegrosql.TypeLonglong) 83 defCaus1 := newDeferredCauset(0) 84 defCaus1.Index, defCaus1.RetType = 0, tp 85 defCaus2 := newDeferredCauset(1) 86 defCaus2.Index, defCaus2.RetType = 1, tp 87 bf, err := newBaseBuiltinFuncWithTp(mock.NewContext(), "", []Expression{defCaus1, defCaus2}, types.ETInt, types.ETInt, types.ETInt) 88 if err != nil { 89 panic(err) 90 } 91 plus := &mockVecPlusIntBuiltinFunc{bf, nil, false} 92 input := chunk.New([]*types.FieldType{tp, tp}, 1024, 1024) 93 buf := chunk.NewDeferredCauset(types.NewFieldType(allegrosql.TypeLonglong), 1024) 94 for i := 0; i < 1024; i++ { 95 input.AppendInt64(0, int64(i)) 96 input.AppendInt64(1, int64(i)) 97 } 98 return plus, input, buf 99 } 100 101 func (s *testEvaluatorSuite) TestMockVecPlusInt(c *C) { 102 plus, input, buf := genMockVecPlusIntBuiltinFunc() 103 plus.enableAlloc = false 104 c.Assert(plus.vecEvalInt(input, buf), IsNil) 105 for i := 0; i < 1024; i++ { 106 c.Assert(buf.IsNull(i), IsFalse) 107 c.Assert(buf.GetInt64(i), Equals, int64(i*2)) 108 } 109 110 plus.enableAlloc = true 111 c.Assert(plus.vecEvalInt(input, buf), IsNil) 112 for i := 0; i < 1024; i++ { 113 c.Assert(buf.IsNull(i), IsFalse) 114 c.Assert(buf.GetInt64(i), Equals, int64(i*2)) 115 } 116 } 117 118 func (s *testVectorizeSuite2) TestMockVecPlusIntParallel(c *C) { 119 plus, input, buf := genMockVecPlusIntBuiltinFunc() 120 plus.enableAlloc = true // it's concurrency-safe if enableAlloc is true 121 var wg sync.WaitGroup 122 for i := 0; i < 50; i++ { 123 wg.Add(1) 124 go func() { 125 result := buf.CopyConstruct(nil) 126 for i := 0; i < 200; i++ { 127 c.Assert(plus.vecEvalInt(input, result), IsNil) 128 for i := 0; i < 1024; i++ { 129 c.Assert(result.IsNull(i), IsFalse) 130 c.Assert(result.GetInt64(i), Equals, int64(i*2)) 131 } 132 } 133 wg.Done() 134 }() 135 } 136 wg.Wait() 137 } 138 139 func BenchmarkDeferredCausetBufferAllocate(b *testing.B) { 140 allocator := newLocalSliceBuffer(1) 141 b.ResetTimer() 142 for i := 0; i < b.N; i++ { 143 buf, _ := allocator.get(types.ETInt, 1024) 144 allocator.put(buf) 145 } 146 } 147 148 func BenchmarkDeferredCausetBufferAllocateParallel(b *testing.B) { 149 allocator := newLocalSliceBuffer(1) 150 b.ResetTimer() 151 b.RunParallel(func(pb *testing.PB) { 152 for pb.Next() { 153 buf, _ := allocator.get(types.ETInt, 1024) 154 allocator.put(buf) 155 } 156 }) 157 } 158 159 func BenchmarkPlusIntBufSlabPredictor(b *testing.B) { 160 plus, input, buf := genMockVecPlusIntBuiltinFunc() 161 names := []string{"enable", "disable"} 162 enable := []bool{true, false} 163 for i := range enable { 164 b.Run(names[i], func(b *testing.B) { 165 plus.enableAlloc = enable[i] 166 b.ResetTimer() 167 for i := 0; i < b.N; i++ { 168 if err := plus.vecEvalInt(input, buf); err != nil { 169 b.Fatal(err) 170 } 171 } 172 }) 173 } 174 } 175 176 type mockBuiltinDouble struct { 177 baseBuiltinFunc 178 179 evalType types.EvalType 180 enableVec bool 181 } 182 183 func (p *mockBuiltinDouble) vectorized() bool { 184 return p.enableVec 185 } 186 187 func (p *mockBuiltinDouble) vecEvalInt(input *chunk.Chunk, result *chunk.DeferredCauset) error { 188 if err := p.args[0].VecEvalInt(p.ctx, input, result); err != nil { 189 return err 190 } 191 i64s := result.Int64s() 192 for i := range i64s { 193 i64s[i] <<= 1 194 } 195 return nil 196 } 197 198 func (p *mockBuiltinDouble) vecEvalReal(input *chunk.Chunk, result *chunk.DeferredCauset) error { 199 if err := p.args[0].VecEvalReal(p.ctx, input, result); err != nil { 200 return err 201 } 202 f64s := result.Float64s() 203 for i := range f64s { 204 f64s[i] *= 2 205 } 206 return nil 207 } 208 209 func (p *mockBuiltinDouble) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error { 210 var buf *chunk.DeferredCauset 211 var err error 212 if buf, err = p.baseBuiltinFunc.bufSlabPredictor.get(p.evalType, input.NumRows()); err != nil { 213 return err 214 } 215 if err := p.args[0].VecEvalString(p.ctx, input, buf); err != nil { 216 return err 217 } 218 result.ReserveString(input.NumRows()) 219 for i := 0; i < input.NumRows(); i++ { 220 str := buf.GetString(i) 221 result.AppendString(str + str) 222 } 223 p.baseBuiltinFunc.bufSlabPredictor.put(buf) 224 return nil 225 } 226 227 func (p *mockBuiltinDouble) vecEvalDecimal(input *chunk.Chunk, result *chunk.DeferredCauset) error { 228 if err := p.args[0].VecEvalDecimal(p.ctx, input, result); err != nil { 229 return err 230 } 231 ds := result.Decimals() 232 for i := range ds { 233 r := new(types.MyDecimal) 234 if err := types.DecimalAdd(&ds[i], &ds[i], r); err != nil { 235 return err 236 } 237 ds[i] = *r 238 } 239 return nil 240 } 241 242 func (p *mockBuiltinDouble) vecEvalTime(input *chunk.Chunk, result *chunk.DeferredCauset) error { 243 if err := p.args[0].VecEvalTime(p.ctx, input, result); err != nil { 244 return err 245 } 246 ts := result.Times() 247 for i := range ts { 248 d, err := ts[i].ConvertToDuration() 249 if err != nil { 250 return err 251 } 252 if ts[i], err = ts[i].Add(p.ctx.GetStochastikVars().StmtCtx, d); err != nil { 253 return err 254 } 255 } 256 return nil 257 } 258 259 func (p *mockBuiltinDouble) vecEvalDuration(input *chunk.Chunk, result *chunk.DeferredCauset) error { 260 if err := p.args[0].VecEvalDuration(p.ctx, input, result); err != nil { 261 return err 262 } 263 ds := result.GoDurations() 264 for i := range ds { 265 ds[i] *= 2 266 } 267 return nil 268 } 269 270 func (p *mockBuiltinDouble) vecEvalJSON(input *chunk.Chunk, result *chunk.DeferredCauset) error { 271 var buf *chunk.DeferredCauset 272 var err error 273 if buf, err = p.baseBuiltinFunc.bufSlabPredictor.get(p.evalType, input.NumRows()); err != nil { 274 return err 275 } 276 if err := p.args[0].VecEvalJSON(p.ctx, input, buf); err != nil { 277 return err 278 } 279 result.ReserveString(input.NumRows()) 280 for i := 0; i < input.NumRows(); i++ { 281 j := buf.GetJSON(i) 282 path, err := json.ParseJSONPathExpr("$.key") 283 if err != nil { 284 return err 285 } 286 ret, ok := j.Extract([]json.PathExpression{path}) 287 if !ok { 288 return errors.Errorf("path not found") 289 } 290 if err := j.UnmarshalJSON([]byte(fmt.Sprintf(`{"key":%v}`, 2*ret.GetInt64()))); err != nil { 291 return err 292 } 293 result.AppendJSON(j) 294 } 295 p.baseBuiltinFunc.bufSlabPredictor.put(buf) 296 return nil 297 } 298 299 func (p *mockBuiltinDouble) evalInt(event chunk.Row) (int64, bool, error) { 300 v, isNull, err := p.args[0].EvalInt(p.ctx, event) 301 if err != nil { 302 return 0, false, err 303 } 304 return v * 2, isNull, nil 305 } 306 307 func (p *mockBuiltinDouble) evalReal(event chunk.Row) (float64, bool, error) { 308 v, isNull, err := p.args[0].EvalReal(p.ctx, event) 309 if err != nil { 310 return 0, false, err 311 } 312 return v * 2, isNull, nil 313 } 314 315 func (p *mockBuiltinDouble) evalString(event chunk.Row) (string, bool, error) { 316 v, isNull, err := p.args[0].EvalString(p.ctx, event) 317 if err != nil { 318 return "", false, err 319 } 320 return v + v, isNull, nil 321 } 322 323 func (p *mockBuiltinDouble) evalDecimal(event chunk.Row) (*types.MyDecimal, bool, error) { 324 v, isNull, err := p.args[0].EvalDecimal(p.ctx, event) 325 if err != nil { 326 return nil, false, err 327 } 328 r := new(types.MyDecimal) 329 if err := types.DecimalAdd(v, v, r); err != nil { 330 return nil, false, err 331 } 332 return r, isNull, nil 333 } 334 335 func (p *mockBuiltinDouble) evalTime(event chunk.Row) (types.Time, bool, error) { 336 v, isNull, err := p.args[0].EvalTime(p.ctx, event) 337 if err != nil { 338 return types.ZeroTime, false, err 339 } 340 d, err := v.ConvertToDuration() 341 if err != nil { 342 return types.ZeroTime, false, err 343 } 344 v, err = v.Add(p.ctx.GetStochastikVars().StmtCtx, d) 345 return v, isNull, err 346 } 347 348 func (p *mockBuiltinDouble) evalDuration(event chunk.Row) (types.Duration, bool, error) { 349 v, isNull, err := p.args[0].EvalDuration(p.ctx, event) 350 if err != nil { 351 return types.Duration{}, false, err 352 } 353 v, err = v.Add(v) 354 return v, isNull, err 355 } 356 357 func (p *mockBuiltinDouble) evalJSON(event chunk.Row) (json.BinaryJSON, bool, error) { 358 j, isNull, err := p.args[0].EvalJSON(p.ctx, event) 359 if err != nil { 360 return json.BinaryJSON{}, false, err 361 } 362 if isNull { 363 return json.BinaryJSON{}, true, nil 364 } 365 path, err := json.ParseJSONPathExpr("$.key") 366 if err != nil { 367 return json.BinaryJSON{}, false, err 368 } 369 ret, ok := j.Extract([]json.PathExpression{path}) 370 if !ok { 371 return json.BinaryJSON{}, true, err 372 } 373 if err := j.UnmarshalJSON([]byte(fmt.Sprintf(`{"key":%v}`, 2*ret.GetInt64()))); err != nil { 374 return json.BinaryJSON{}, false, err 375 } 376 return j, false, nil 377 } 378 379 func convertETType(eType types.EvalType) (mysqlType byte) { 380 switch eType { 381 case types.ETInt: 382 mysqlType = allegrosql.TypeLonglong 383 case types.ETReal: 384 mysqlType = allegrosql.TypeDouble 385 case types.ETDecimal: 386 mysqlType = allegrosql.TypeNewDecimal 387 case types.ETDuration: 388 mysqlType = allegrosql.TypeDuration 389 case types.ETJson: 390 mysqlType = allegrosql.TypeJSON 391 case types.ETString: 392 mysqlType = allegrosql.TypeVarString 393 case types.ETDatetime: 394 mysqlType = allegrosql.TypeDatetime 395 } 396 return 397 } 398 399 func genMockRowDouble(eType types.EvalType, enableVec bool) (builtinFunc, *chunk.Chunk, *chunk.DeferredCauset, error) { 400 mysqlType := convertETType(eType) 401 tp := types.NewFieldType(mysqlType) 402 defCaus1 := newDeferredCauset(1) 403 defCaus1.Index = 0 404 defCaus1.RetType = tp 405 bf, err := newBaseBuiltinFuncWithTp(mock.NewContext(), "", []Expression{defCaus1}, eType, eType) 406 if err != nil { 407 return nil, nil, nil, err 408 } 409 rowDouble := &mockBuiltinDouble{bf, eType, enableVec} 410 input := chunk.New([]*types.FieldType{tp}, 1024, 1024) 411 buf := chunk.NewDeferredCauset(types.NewFieldType(convertETType(eType)), 1024) 412 for i := 0; i < 1024; i++ { 413 switch eType { 414 case types.ETInt: 415 input.AppendInt64(0, int64(i)) 416 case types.ETReal: 417 input.AppendFloat64(0, float64(i)) 418 case types.ETDecimal: 419 dec := new(types.MyDecimal) 420 if err := dec.FromFloat64(float64(i)); err != nil { 421 return nil, nil, nil, err 422 } 423 input.AppendMyDecimal(0, dec) 424 case types.ETDuration: 425 input.AppendDuration(0, types.Duration{Duration: time.Duration(i)}) 426 case types.ETJson: 427 j := new(json.BinaryJSON) 428 if err := j.UnmarshalJSON([]byte(fmt.Sprintf(`{"key":%v}`, i))); err != nil { 429 return nil, nil, nil, err 430 } 431 input.AppendJSON(0, *j) 432 case types.ETString: 433 input.AppendString(0, fmt.Sprintf("%v", i)) 434 case types.ETDatetime: 435 t := types.FromDate(i, 0, 0, 0, 0, 0, 0) 436 input.AppendTime(0, types.NewTime(t, mysqlType, 0)) 437 } 438 } 439 return rowDouble, input, buf, nil 440 } 441 442 func (s *testEvaluatorSuite) checkVecEval(c *C, eType types.EvalType, sel []int, result *chunk.DeferredCauset) { 443 if sel == nil { 444 for i := 0; i < 1024; i++ { 445 sel = append(sel, i) 446 } 447 } 448 switch eType { 449 case types.ETInt: 450 i64s := result.Int64s() 451 c.Assert(len(i64s), Equals, len(sel)) 452 for i, j := range sel { 453 c.Assert(i64s[i], Equals, int64(j*2)) 454 } 455 case types.ETReal: 456 f64s := result.Float64s() 457 c.Assert(len(f64s), Equals, len(sel)) 458 for i, j := range sel { 459 c.Assert(f64s[i], Equals, float64(j*2)) 460 } 461 case types.ETDecimal: 462 ds := result.Decimals() 463 c.Assert(len(ds), Equals, len(sel)) 464 for i, j := range sel { 465 dec := new(types.MyDecimal) 466 c.Assert(dec.FromFloat64(float64(j)), IsNil) 467 rst := new(types.MyDecimal) 468 c.Assert(types.DecimalAdd(dec, dec, rst), IsNil) 469 c.Assert(rst.Compare(&ds[i]), Equals, 0) 470 } 471 case types.ETDuration: 472 ds := result.GoDurations() 473 c.Assert(len(ds), Equals, len(sel)) 474 for i, j := range sel { 475 c.Assert(ds[i], Equals, time.Duration(j+j)) 476 } 477 case types.ETDatetime: 478 ds := result.Times() 479 c.Assert(len(ds), Equals, len(sel)) 480 for i, j := range sel { 481 gt := types.FromDate(j, 0, 0, 0, 0, 0, 0) 482 t := types.NewTime(gt, convertETType(eType), 0) 483 d, err := t.ConvertToDuration() 484 c.Assert(err, IsNil) 485 v, err := t.Add(mock.NewContext().GetStochastikVars().StmtCtx, d) 486 c.Assert(err, IsNil) 487 c.Assert(v.Compare(ds[i]), Equals, 0) 488 } 489 case types.ETJson: 490 for i, j := range sel { 491 path, err := json.ParseJSONPathExpr("$.key") 492 c.Assert(err, IsNil) 493 ret, ok := result.GetJSON(i).Extract([]json.PathExpression{path}) 494 c.Assert(ok, IsTrue) 495 c.Assert(ret.GetInt64(), Equals, int64(j*2)) 496 } 497 case types.ETString: 498 for i, j := range sel { 499 c.Assert(result.GetString(i), Equals, fmt.Sprintf("%v%v", j, j)) 500 } 501 } 502 } 503 504 func vecEvalType(f builtinFunc, eType types.EvalType, input *chunk.Chunk, result *chunk.DeferredCauset) error { 505 switch eType { 506 case types.ETInt: 507 return f.vecEvalInt(input, result) 508 case types.ETReal: 509 return f.vecEvalReal(input, result) 510 case types.ETDecimal: 511 return f.vecEvalDecimal(input, result) 512 case types.ETDuration: 513 return f.vecEvalDuration(input, result) 514 case types.ETString: 515 return f.vecEvalString(input, result) 516 case types.ETDatetime: 517 return f.vecEvalTime(input, result) 518 case types.ETJson: 519 return f.vecEvalJSON(input, result) 520 } 521 panic("not implement") 522 } 523 524 func (s *testEvaluatorSuite) TestDoubleRow2Vec(c *C) { 525 eTypes := []types.EvalType{types.ETInt, types.ETReal, types.ETDecimal, types.ETDuration, types.ETString, types.ETDatetime, types.ETJson} 526 for _, eType := range eTypes { 527 rowDouble, input, result, err := genMockRowDouble(eType, false) 528 c.Assert(err, IsNil) 529 c.Assert(vecEvalType(rowDouble, eType, input, result), IsNil) 530 s.checkVecEval(c, eType, nil, result) 531 532 sel := []int{0} 533 for { 534 end := sel[len(sel)-1] 535 gap := 1024 - end 536 if gap < 10 { 537 break 538 } 539 sel = append(sel, end+rand.Intn(gap-1)+1) 540 } 541 input.SetSel(sel) 542 c.Assert(vecEvalType(rowDouble, eType, input, result), IsNil) 543 544 s.checkVecEval(c, eType, sel, result) 545 } 546 } 547 548 func (s *testEvaluatorSuite) TestDoubleVec2Row(c *C) { 549 eTypes := []types.EvalType{types.ETInt, types.ETReal, types.ETDecimal, types.ETDuration, types.ETString, types.ETDatetime, types.ETJson} 550 for _, eType := range eTypes { 551 rowDouble, input, result, err := genMockRowDouble(eType, true) 552 result.Reset(eType) 553 c.Assert(err, IsNil) 554 it := chunk.NewIterator4Chunk(input) 555 for event := it.Begin(); event != it.End(); event = it.Next() { 556 switch eType { 557 case types.ETInt: 558 v, _, err := rowDouble.evalInt(event) 559 c.Assert(err, IsNil) 560 result.AppendInt64(v) 561 case types.ETReal: 562 v, _, err := rowDouble.evalReal(event) 563 c.Assert(err, IsNil) 564 result.AppendFloat64(v) 565 case types.ETDecimal: 566 v, _, err := rowDouble.evalDecimal(event) 567 c.Assert(err, IsNil) 568 result.AppendMyDecimal(v) 569 case types.ETDuration: 570 v, _, err := rowDouble.evalDuration(event) 571 c.Assert(err, IsNil) 572 result.AppendDuration(v) 573 case types.ETString: 574 v, _, err := rowDouble.evalString(event) 575 c.Assert(err, IsNil) 576 result.AppendString(v) 577 case types.ETDatetime: 578 v, _, err := rowDouble.evalTime(event) 579 c.Assert(err, IsNil) 580 result.AppendTime(v) 581 case types.ETJson: 582 v, _, err := rowDouble.evalJSON(event) 583 c.Assert(err, IsNil) 584 result.AppendJSON(v) 585 } 586 } 587 s.checkVecEval(c, eType, nil, result) 588 } 589 } 590 591 func evalRows(b *testing.B, it *chunk.Iterator4Chunk, eType types.EvalType, result *chunk.DeferredCauset, rowDouble builtinFunc) { 592 switch eType { 593 case types.ETInt: 594 for i := 0; i < b.N; i++ { 595 result.Reset(eType) 596 for r := it.Begin(); r != it.End(); r = it.Next() { 597 v, isNull, err := rowDouble.evalInt(r) 598 if err != nil { 599 b.Fatal(err) 600 } 601 if isNull { 602 result.AppendNull() 603 } else { 604 result.AppendInt64(v) 605 } 606 } 607 } 608 case types.ETReal: 609 for i := 0; i < b.N; i++ { 610 result.Reset(eType) 611 for r := it.Begin(); r != it.End(); r = it.Next() { 612 v, isNull, err := rowDouble.evalReal(r) 613 if err != nil { 614 b.Fatal(err) 615 } 616 if isNull { 617 result.AppendNull() 618 } else { 619 result.AppendFloat64(v) 620 } 621 } 622 } 623 case types.ETDecimal: 624 for i := 0; i < b.N; i++ { 625 result.Reset(eType) 626 for r := it.Begin(); r != it.End(); r = it.Next() { 627 v, isNull, err := rowDouble.evalDecimal(r) 628 if err != nil { 629 b.Fatal(err) 630 } 631 if isNull { 632 result.AppendNull() 633 } else { 634 result.AppendMyDecimal(v) 635 } 636 } 637 } 638 case types.ETDuration: 639 for i := 0; i < b.N; i++ { 640 result.Reset(eType) 641 for r := it.Begin(); r != it.End(); r = it.Next() { 642 v, isNull, err := rowDouble.evalDuration(r) 643 if err != nil { 644 b.Fatal(err) 645 } 646 if isNull { 647 result.AppendNull() 648 } else { 649 result.AppendDuration(v) 650 } 651 } 652 } 653 case types.ETString: 654 for i := 0; i < b.N; i++ { 655 result.Reset(eType) 656 for r := it.Begin(); r != it.End(); r = it.Next() { 657 v, isNull, err := rowDouble.evalString(r) 658 if err != nil { 659 b.Fatal(err) 660 } 661 if isNull { 662 result.AppendNull() 663 } else { 664 result.AppendString(v) 665 } 666 } 667 } 668 case types.ETDatetime: 669 for i := 0; i < b.N; i++ { 670 result.Reset(eType) 671 for r := it.Begin(); r != it.End(); r = it.Next() { 672 v, isNull, err := rowDouble.evalTime(r) 673 if err != nil { 674 b.Fatal(err) 675 } 676 if isNull { 677 result.AppendNull() 678 } else { 679 result.AppendTime(v) 680 } 681 } 682 } 683 case types.ETJson: 684 for i := 0; i < b.N; i++ { 685 result.Reset(eType) 686 for r := it.Begin(); r != it.End(); r = it.Next() { 687 v, isNull, err := rowDouble.evalJSON(r) 688 if err != nil { 689 b.Fatal(err) 690 } 691 if isNull { 692 result.AppendNull() 693 } else { 694 result.AppendJSON(v) 695 } 696 } 697 } 698 } 699 } 700 701 func BenchmarkMockDoubleRow(b *testing.B) { 702 typeNames := []string{"Int", "Real", "Decimal", "Duration", "String", "Datetime", "JSON"} 703 eTypes := []types.EvalType{types.ETInt, types.ETReal, types.ETDecimal, types.ETDuration, types.ETString, types.ETDatetime, types.ETJson} 704 for i, eType := range eTypes { 705 b.Run(typeNames[i], func(b *testing.B) { 706 rowDouble, input, result, _ := genMockRowDouble(eType, false) 707 it := chunk.NewIterator4Chunk(input) 708 b.ResetTimer() 709 evalRows(b, it, eType, result, rowDouble) 710 }) 711 } 712 } 713 714 func BenchmarkMockDoubleVec(b *testing.B) { 715 typeNames := []string{"Int", "Real", "Decimal", "Duration", "String", "Datetime", "JSON"} 716 eTypes := []types.EvalType{types.ETInt, types.ETReal, types.ETDecimal, types.ETDuration, types.ETString, types.ETDatetime, types.ETJson} 717 for i, eType := range eTypes { 718 b.Run(typeNames[i], func(b *testing.B) { 719 rowDouble, input, result, _ := genMockRowDouble(eType, true) 720 b.ResetTimer() 721 for i := 0; i < b.N; i++ { 722 if err := vecEvalType(rowDouble, eType, input, result); err != nil { 723 b.Fatal(err) 724 } 725 } 726 }) 727 } 728 } 729 730 func (s *testEvaluatorSuite) TestVectorizedCheck(c *C) { 731 con := &Constant{} 732 c.Assert(con.Vectorized(), IsTrue) 733 defCaus := &DeferredCauset{} 734 c.Assert(defCaus.Vectorized(), IsTrue) 735 cor := CorrelatedDeferredCauset{DeferredCauset: *defCaus} 736 c.Assert(cor.Vectorized(), IsTrue) 737 738 vecF, _, _, _ := genMockRowDouble(types.ETInt, true) 739 sf := &ScalarFunction{Function: vecF} 740 c.Assert(sf.Vectorized(), IsTrue) 741 742 rowF, _, _, _ := genMockRowDouble(types.ETInt, false) 743 sf = &ScalarFunction{Function: rowF} 744 c.Assert(sf.Vectorized(), IsFalse) 745 } 746 747 func genFloat32DefCaus() (*DeferredCauset, *chunk.Chunk, *chunk.DeferredCauset) { 748 typeFloat := types.NewFieldType(allegrosql.TypeFloat) 749 defCaus := &DeferredCauset{Index: 0, RetType: typeFloat} 750 chk := chunk.NewChunkWithCapacity([]*types.FieldType{typeFloat}, 1024) 751 for i := 0; i < 1024; i++ { 752 chk.AppendFloat32(0, rand.Float32()) 753 } 754 result := chunk.NewDeferredCauset(typeFloat, 1024) 755 return defCaus, chk, result 756 } 757 758 func (s *testEvaluatorSuite) TestFloat32DefCausVec(c *C) { 759 defCaus, chk, result := genFloat32DefCaus() 760 ctx := mock.NewContext() 761 c.Assert(defCaus.VecEvalReal(ctx, chk, result), IsNil) 762 it := chunk.NewIterator4Chunk(chk) 763 i := 0 764 for event := it.Begin(); event != it.End(); event = it.Next() { 765 v, _, err := defCaus.EvalReal(ctx, event) 766 c.Assert(err, IsNil) 767 c.Assert(v, Equals, result.GetFloat64(i)) 768 i++ 769 } 770 771 // set Sel 772 n := chk.NumRows() 773 sel := make([]int, n/2) 774 for i := 0; i < n; i += 2 { 775 sel = append(sel, i) 776 } 777 chk.SetSel(sel) 778 c.Assert(defCaus.VecEvalReal(ctx, chk, result), IsNil) 779 i = 0 780 for event := it.Begin(); event != it.End(); event = it.Next() { 781 v, _, err := defCaus.EvalReal(ctx, event) 782 c.Assert(err, IsNil) 783 c.Assert(v, Equals, result.GetFloat64(i)) 784 i++ 785 } 786 787 c.Assert(defCaus.VecEvalReal(ctx, chk, result), IsNil) 788 } 789 790 func BenchmarkFloat32DefCausRow(b *testing.B) { 791 defCaus, chk, _ := genFloat32DefCaus() 792 ctx := mock.NewContext() 793 it := chunk.NewIterator4Chunk(chk) 794 b.ResetTimer() 795 for i := 0; i < b.N; i++ { 796 for event := it.Begin(); event != it.End(); event = it.Next() { 797 if _, _, err := defCaus.EvalReal(ctx, event); err != nil { 798 b.Fatal(err) 799 } 800 801 } 802 } 803 } 804 805 func BenchmarkFloat32DefCausVec(b *testing.B) { 806 defCaus, chk, result := genFloat32DefCaus() 807 ctx := mock.NewContext() 808 b.ResetTimer() 809 for i := 0; i < b.N; i++ { 810 if err := defCaus.VecEvalReal(ctx, chk, result); err != nil { 811 b.Fatal(err) 812 } 813 } 814 }