forked from tikv/tikv
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refine coprocessor benchmarks (tikv#4501)
Signed-off-by: Breezewish <breezewish@pingcap.com>
- Loading branch information
1 parent
6a3f632
commit 6d6e2f8
Showing
27 changed files
with
3,681 additions
and
637 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,246 @@ | ||
// Copyright 2019 TiKV Project Authors. Licensed under Apache-2.0. | ||
|
||
mod util; | ||
|
||
use cop_datatype::FieldTypeTp; | ||
use tipb::expression::{ExprType, ScalarFuncSig}; | ||
use tipb_helper::ExprDefBuilder; | ||
|
||
use crate::util::{BenchCase, FixtureBuilder}; | ||
|
||
/// COUNT(1) GROUP BY COL where COL is a int column. | ||
/// Each row is a new group. | ||
fn bench_hash_aggr_count_1_group_by_int_col(b: &mut criterion::Bencher, input: &Input) { | ||
let fb = FixtureBuilder::new(input.src_rows).push_column_i64_0_n(); | ||
let group_by = vec![ExprDefBuilder::column_ref(0, FieldTypeTp::LongLong).build()]; | ||
let expr = ExprDefBuilder::aggr_func(ExprType::Count, FieldTypeTp::LongLong) | ||
.push_child(ExprDefBuilder::constant_int(1)) | ||
.build(); | ||
input.bencher.bench(b, &fb, &group_by, &[expr]); | ||
} | ||
|
||
/// COUNT(1) GROUP BY COL where COL is a int column. | ||
/// There will be two groups totally. | ||
fn bench_hash_aggr_count_1_group_by_int_col_2_groups(b: &mut criterion::Bencher, input: &Input) { | ||
let fb = FixtureBuilder::new(input.src_rows).push_column_i64_sampled(&[0x123456, 0xCCCC]); | ||
let group_by = vec![ExprDefBuilder::column_ref(0, FieldTypeTp::LongLong).build()]; | ||
let expr = ExprDefBuilder::aggr_func(ExprType::Count, FieldTypeTp::LongLong) | ||
.push_child(ExprDefBuilder::constant_int(1)) | ||
.build(); | ||
input.bencher.bench(b, &fb, &group_by, &[expr]); | ||
} | ||
|
||
/// COUNT(1) GROUP BY COL > X. | ||
/// Half of the row belong to one group and the rest belong to another group. Thus there are | ||
/// totally two groups. | ||
fn bench_hash_aggr_count_1_group_by_fn_2_groups(b: &mut criterion::Bencher, input: &Input) { | ||
let fb = FixtureBuilder::new(input.src_rows).push_column_i64_0_n(); | ||
let group_by = vec![ | ||
ExprDefBuilder::scalar_func(ScalarFuncSig::GTInt, FieldTypeTp::LongLong) | ||
.push_child(ExprDefBuilder::column_ref(0, FieldTypeTp::LongLong)) | ||
.push_child(ExprDefBuilder::constant_int((input.src_rows / 2) as i64)) | ||
.build(), | ||
]; | ||
let expr = ExprDefBuilder::aggr_func(ExprType::Count, FieldTypeTp::LongLong) | ||
.push_child(ExprDefBuilder::constant_int(1)) | ||
.build(); | ||
input.bencher.bench(b, &fb, &group_by, &[expr]); | ||
} | ||
|
||
/// COUNT(1) GROUP BY COL where COL is a decimal column (by slow hash aggr). | ||
/// Each row is a new group. | ||
fn bench_hash_aggr_count_1_group_by_decimal_col(b: &mut criterion::Bencher, input: &Input) { | ||
let fb = FixtureBuilder::new(input.src_rows).push_column_decimal_0_n(); | ||
let group_by = vec![ExprDefBuilder::column_ref(0, FieldTypeTp::NewDecimal).build()]; | ||
let expr = ExprDefBuilder::aggr_func(ExprType::Count, FieldTypeTp::LongLong) | ||
.push_child(ExprDefBuilder::constant_int(1)) | ||
.build(); | ||
input.bencher.bench(b, &fb, &group_by, &[expr]); | ||
} | ||
|
||
/// COUNT(1) GROUP BY COL where COL is a decimal column (by slow hash aggr). | ||
/// There will be two groups totally. | ||
fn bench_hash_aggr_count_1_group_by_decimal_col_2_groups( | ||
b: &mut criterion::Bencher, | ||
input: &Input, | ||
) { | ||
let fb = FixtureBuilder::new(input.src_rows) | ||
.push_column_decimal_sampled(&["680644618.9451818", "767257805709854474.824642776567"]); | ||
let group_by = vec![ExprDefBuilder::column_ref(0, FieldTypeTp::NewDecimal).build()]; | ||
let expr = ExprDefBuilder::aggr_func(ExprType::Count, FieldTypeTp::LongLong) | ||
.push_child(ExprDefBuilder::constant_int(1)) | ||
.build(); | ||
input.bencher.bench(b, &fb, &group_by, &[expr]); | ||
} | ||
|
||
/// COUNT(1) GROUP BY COL1, COL2 where COL1 is a int column and COL2 is a real column. | ||
/// Each row is a new group. | ||
fn bench_hash_aggr_count_1_group_by_int_col_real_col(b: &mut criterion::Bencher, input: &Input) { | ||
let fb = FixtureBuilder::new(input.src_rows) | ||
.push_column_i64_random() | ||
.push_column_f64_random(); | ||
let group_by = vec![ | ||
ExprDefBuilder::column_ref(0, FieldTypeTp::LongLong).build(), | ||
ExprDefBuilder::column_ref(1, FieldTypeTp::Double).build(), | ||
]; | ||
let expr = ExprDefBuilder::aggr_func(ExprType::Count, FieldTypeTp::LongLong) | ||
.push_child(ExprDefBuilder::constant_int(1)) | ||
.build(); | ||
input.bencher.bench(b, &fb, &group_by, &[expr]); | ||
} | ||
|
||
/// COUNT(1) GROUP BY COL1, COL2 where COL1 is a int column and COL2 is a real column. | ||
/// There will be two groups totally. | ||
fn bench_hash_aggr_count_1_group_by_int_col_real_col_2_groups( | ||
b: &mut criterion::Bencher, | ||
input: &Input, | ||
) { | ||
let fb = FixtureBuilder::new(input.src_rows) | ||
.push_column_i64_sampled(&[0xDEADBEEF, 0xFEE1DEAD]) | ||
.push_column_f64_sampled(&[680644618.9451818]); | ||
let group_by = vec![ | ||
ExprDefBuilder::column_ref(0, FieldTypeTp::LongLong).build(), | ||
ExprDefBuilder::column_ref(1, FieldTypeTp::Double).build(), | ||
]; | ||
let expr = ExprDefBuilder::aggr_func(ExprType::Count, FieldTypeTp::LongLong) | ||
.push_child(ExprDefBuilder::constant_int(1)) | ||
.build(); | ||
input.bencher.bench(b, &fb, &group_by, &[expr]); | ||
} | ||
|
||
/// COUNT(1), FIRST(COL3) GROUP BY COL1, COL2 where COL1 is a int column and | ||
/// COL2, COL3 are real columns. Each row is a new group. | ||
fn bench_hash_aggr_count_1_first_group_by_int_col_real_col( | ||
b: &mut criterion::Bencher, | ||
input: &Input, | ||
) { | ||
let fb = FixtureBuilder::new(input.src_rows) | ||
.push_column_i64_random() | ||
.push_column_f64_random() | ||
.push_column_f64_random(); | ||
let group_by = vec![ | ||
ExprDefBuilder::column_ref(0, FieldTypeTp::LongLong).build(), | ||
ExprDefBuilder::column_ref(1, FieldTypeTp::Double).build(), | ||
]; | ||
let expr = [ | ||
ExprDefBuilder::aggr_func(ExprType::Count, FieldTypeTp::LongLong) | ||
.push_child(ExprDefBuilder::constant_int(1)) | ||
.build(), | ||
ExprDefBuilder::aggr_func(ExprType::First, FieldTypeTp::Double) | ||
.push_child(ExprDefBuilder::column_ref(2, FieldTypeTp::Double)) | ||
.build(), | ||
]; | ||
input.bencher.bench(b, &fb, &group_by, &expr); | ||
} | ||
|
||
/// COUNT(1), FIRST(COL3) GROUP BY COL1, COL2 where COL1 is a int column and | ||
/// COL2, COL3 are real columns. There will be two groups totally. | ||
fn bench_hash_aggr_count_1_first_group_by_int_col_real_col_2_groups( | ||
b: &mut criterion::Bencher, | ||
input: &Input, | ||
) { | ||
let fb = FixtureBuilder::new(input.src_rows) | ||
.push_column_i64_sampled(&[0xDEADBEEF, 0xFEE1DEAD]) | ||
.push_column_f64_sampled(&[680644618.9451818]) | ||
.push_column_f64_random(); | ||
let group_by = vec![ | ||
ExprDefBuilder::column_ref(0, FieldTypeTp::LongLong).build(), | ||
ExprDefBuilder::column_ref(1, FieldTypeTp::Double).build(), | ||
]; | ||
let expr = [ | ||
ExprDefBuilder::aggr_func(ExprType::Count, FieldTypeTp::LongLong) | ||
.push_child(ExprDefBuilder::constant_int(1)) | ||
.build(), | ||
ExprDefBuilder::aggr_func(ExprType::First, FieldTypeTp::Double) | ||
.push_child(ExprDefBuilder::column_ref(2, FieldTypeTp::Double)) | ||
.build(), | ||
]; | ||
input.bencher.bench(b, &fb, &group_by, &expr); | ||
} | ||
|
||
#[derive(Clone)] | ||
struct Input { | ||
/// How many rows to aggregate | ||
src_rows: usize, | ||
|
||
/// The aggregate executor (batch / normal) to use | ||
bencher: Box<dyn util::HashAggrBencher>, | ||
} | ||
|
||
impl std::fmt::Debug for Input { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
write!(f, "{}/rows={}", self.bencher.name(), self.src_rows) | ||
} | ||
} | ||
|
||
pub fn bench(c: &mut criterion::Criterion) { | ||
let mut inputs = vec![]; | ||
|
||
let mut rows_options = vec![5000]; | ||
if crate::util::bench_level() >= 1 { | ||
rows_options.push(5); | ||
} | ||
if crate::util::bench_level() >= 2 { | ||
rows_options.push(1); | ||
} | ||
let bencher_options: Vec<Box<dyn util::HashAggrBencher>> = | ||
vec![Box::new(util::NormalBencher), Box::new(util::BatchBencher)]; | ||
|
||
for rows in &rows_options { | ||
for bencher in &bencher_options { | ||
inputs.push(Input { | ||
src_rows: *rows, | ||
bencher: bencher.box_clone(), | ||
}); | ||
} | ||
} | ||
|
||
let mut cases = vec![ | ||
BenchCase::new( | ||
"hash_aggr_count_1_group_by_int_col_2_groups", | ||
bench_hash_aggr_count_1_group_by_int_col_2_groups, | ||
), | ||
BenchCase::new( | ||
"hash_aggr_count_1_group_by_decimal_col_2_groups", | ||
bench_hash_aggr_count_1_group_by_decimal_col_2_groups, | ||
), | ||
BenchCase::new( | ||
"hash_aggr_count_1_group_by_int_col_real_col_2_groups", | ||
bench_hash_aggr_count_1_group_by_int_col_real_col_2_groups, | ||
), | ||
BenchCase::new( | ||
"hash_aggr_count_1_first_group_by_int_col_real_col_2_groups", | ||
bench_hash_aggr_count_1_first_group_by_int_col_real_col_2_groups, | ||
), | ||
]; | ||
if crate::util::bench_level() >= 1 { | ||
let mut additional_cases = vec![ | ||
BenchCase::new( | ||
"hash_aggr_count_1_group_by_fn_2_groups", | ||
bench_hash_aggr_count_1_group_by_fn_2_groups, | ||
), | ||
BenchCase::new( | ||
"hash_aggr_count_1_group_by_int_col", | ||
bench_hash_aggr_count_1_group_by_int_col, | ||
), | ||
BenchCase::new( | ||
"hash_aggr_count_1_group_by_decimal_col", | ||
bench_hash_aggr_count_1_group_by_decimal_col, | ||
), | ||
BenchCase::new( | ||
"hash_aggr_count_1_group_by_int_col_real_col", | ||
bench_hash_aggr_count_1_group_by_int_col_real_col, | ||
), | ||
BenchCase::new( | ||
"hash_aggr_count_1_first_group_by_int_col_real_col", | ||
bench_hash_aggr_count_1_first_group_by_int_col_real_col, | ||
), | ||
]; | ||
cases.append(&mut additional_cases); | ||
} | ||
|
||
cases.sort(); | ||
for case in cases { | ||
c.bench_function_over_inputs(case.name, case.f, inputs.clone()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
// Copyright 2019 TiKV Project Authors. Licensed under Apache-2.0. | ||
|
||
use std::sync::Arc; | ||
|
||
use criterion::black_box; | ||
|
||
use tipb::executor::Aggregation; | ||
use tipb::expression::Expr; | ||
|
||
use tikv::coprocessor::dag::batch::executors::BatchFastHashAggregationExecutor; | ||
use tikv::coprocessor::dag::batch::executors::BatchSlowHashAggregationExecutor; | ||
use tikv::coprocessor::dag::batch::interface::*; | ||
use tikv::coprocessor::dag::executor::{Executor, HashAggExecutor}; | ||
use tikv::coprocessor::dag::expr::EvalConfig; | ||
|
||
use crate::util::bencher::Bencher; | ||
use crate::util::FixtureBuilder; | ||
|
||
pub trait HashAggrBencher { | ||
fn name(&self) -> &'static str; | ||
|
||
fn bench( | ||
&self, | ||
b: &mut criterion::Bencher, | ||
fb: &FixtureBuilder, | ||
group_by_expr: &[Expr], | ||
aggr_expr: &[Expr], | ||
); | ||
|
||
fn box_clone(&self) -> Box<dyn HashAggrBencher>; | ||
} | ||
|
||
impl Clone for Box<dyn HashAggrBencher> { | ||
#[inline] | ||
fn clone(&self) -> Self { | ||
self.box_clone() | ||
} | ||
} | ||
|
||
/// A bencher that will use normal hash aggregation executor to bench the giving aggregate | ||
/// expression. | ||
pub struct NormalBencher; | ||
|
||
impl HashAggrBencher for NormalBencher { | ||
fn name(&self) -> &'static str { | ||
"normal" | ||
} | ||
|
||
fn bench( | ||
&self, | ||
b: &mut criterion::Bencher, | ||
fb: &FixtureBuilder, | ||
group_by_expr: &[Expr], | ||
aggr_expr: &[Expr], | ||
) { | ||
crate::util::bencher::NormalNextAllBencher::new(|| { | ||
let mut meta = Aggregation::new(); | ||
meta.set_agg_func(aggr_expr.to_vec().into()); | ||
meta.set_group_by(group_by_expr.to_vec().into()); | ||
let src = fb.clone().build_normal_fixture_executor(); | ||
let ex = HashAggExecutor::new( | ||
black_box(meta), | ||
black_box(Arc::new(EvalConfig::default())), | ||
black_box(Box::new(src)), | ||
) | ||
.unwrap(); | ||
Box::new(ex) as Box<dyn Executor> | ||
}) | ||
.bench(b); | ||
} | ||
|
||
fn box_clone(&self) -> Box<dyn HashAggrBencher> { | ||
Box::new(Self) | ||
} | ||
} | ||
|
||
/// A bencher that will use batch hash aggregation executor to bench the giving aggregate | ||
/// expression. | ||
pub struct BatchBencher; | ||
|
||
impl HashAggrBencher for BatchBencher { | ||
fn name(&self) -> &'static str { | ||
"batch" | ||
} | ||
|
||
fn bench( | ||
&self, | ||
b: &mut criterion::Bencher, | ||
fb: &FixtureBuilder, | ||
group_by_expr: &[Expr], | ||
aggr_expr: &[Expr], | ||
) { | ||
crate::util::bencher::BatchNextAllBencher::new(|| { | ||
let src = fb.clone().build_batch_fixture_executor(); | ||
let mut meta = Aggregation::new(); | ||
meta.set_agg_func(aggr_expr.to_vec().into()); | ||
meta.set_group_by(group_by_expr.to_vec().into()); | ||
if BatchFastHashAggregationExecutor::check_supported(&meta).is_ok() { | ||
let ex = BatchFastHashAggregationExecutor::new( | ||
black_box(Arc::new(EvalConfig::default())), | ||
black_box(Box::new(src)), | ||
black_box(group_by_expr.to_vec()), | ||
black_box(aggr_expr.to_vec()), | ||
) | ||
.unwrap(); | ||
Box::new(ex) as Box<dyn BatchExecutor> | ||
} else { | ||
let ex = BatchSlowHashAggregationExecutor::new( | ||
black_box(Arc::new(EvalConfig::default())), | ||
black_box(Box::new(src)), | ||
black_box(group_by_expr.to_vec()), | ||
black_box(aggr_expr.to_vec()), | ||
) | ||
.unwrap(); | ||
Box::new(ex) as Box<dyn BatchExecutor> | ||
} | ||
}) | ||
.bench(b); | ||
} | ||
|
||
fn box_clone(&self) -> Box<dyn HashAggrBencher> { | ||
Box::new(Self) | ||
} | ||
} |
Oops, something went wrong.