Skip to content

Commit 934d56f

Browse files
committed
chore: add bitmap scalar function benchmarks
Added a `bitmap_scalar` bench group covering: - bitmap_contains - bitmap_count - bitmap_min - bitmap_max - bitmap_and - bitmap_has_any - bitmap_has_all
1 parent 2501da7 commit 934d56f

1 file changed

Lines changed: 305 additions & 0 deletions

File tree

src/query/functions/benches/bench.rs

Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,311 @@ mod bitmap {
308308
}
309309
}
310310

311+
#[divan::bench_group(max_time = 0.5)]
312+
mod bitmap_scalar {
313+
use databend_common_expression::BlockEntry;
314+
use databend_common_expression::DataBlock;
315+
use databend_common_expression::Evaluator;
316+
use databend_common_expression::Expr;
317+
use databend_common_expression::FromData;
318+
use databend_common_expression::FunctionContext;
319+
use databend_common_expression::type_check;
320+
use databend_common_expression::types::BitmapType;
321+
use databend_common_expression::types::DataType;
322+
use databend_common_expression_test_support as parser;
323+
use databend_common_functions::BUILTIN_FUNCTIONS;
324+
use databend_common_io::HybridBitmap;
325+
326+
fn serialize_bitmap(bitmap: &HybridBitmap) -> Vec<u8> {
327+
let mut data = Vec::new();
328+
bitmap.serialize_into(&mut data).unwrap();
329+
data
330+
}
331+
332+
fn bitmap_entry(bitmap: &HybridBitmap) -> BlockEntry {
333+
BitmapType::from_data(vec![serialize_bitmap(bitmap); 1]).into()
334+
}
335+
336+
fn build_expr(sql: &str, columns: &[(&str, DataType)]) -> Expr {
337+
let raw_expr = parser::parse_raw_expr(sql, columns, &BUILTIN_FUNCTIONS);
338+
type_check::check(&raw_expr, &BUILTIN_FUNCTIONS).unwrap()
339+
}
340+
341+
fn eval_block(expr: &Expr, block: &DataBlock) {
342+
let func_ctx = FunctionContext::default();
343+
let evaluator = Evaluator::new(block, &func_ctx, &BUILTIN_FUNCTIONS);
344+
let result = evaluator.run(expr).unwrap();
345+
divan::black_box(result);
346+
}
347+
348+
fn large_bitmap() -> HybridBitmap {
349+
let mut bm = HybridBitmap::new();
350+
for i in 0..10u64 {
351+
for v in i * 65536..i * 65536 + 5000 {
352+
bm.insert(v);
353+
}
354+
}
355+
for j in 10..50u64 {
356+
for v in j * 65536..j * 65536 + 100 {
357+
bm.insert(v);
358+
}
359+
}
360+
bm
361+
}
362+
363+
fn overlap_large_bitmap() -> HybridBitmap {
364+
let mut bm = HybridBitmap::new();
365+
for i in 5..10u64 {
366+
for v in i * 65536 - 3000..i * 65536 + 5000 {
367+
bm.insert(v);
368+
}
369+
}
370+
for i in 10..50u64 {
371+
for v in i * 65536 - 30..i * 65536 + 50 {
372+
bm.insert(v);
373+
}
374+
}
375+
bm
376+
}
377+
378+
fn subset_large_bitmap() -> HybridBitmap {
379+
let mut bm = HybridBitmap::new();
380+
for i in 0..5u64 {
381+
for v in i * 65536 + 1000..i * 65536 + 4000 {
382+
bm.insert(v);
383+
}
384+
}
385+
for j in 10..30u64 {
386+
for v in j * 65536 + 10..j * 65536 + 90 {
387+
bm.insert(v);
388+
}
389+
}
390+
bm
391+
}
392+
393+
fn disjoint_large_bitmap() -> HybridBitmap {
394+
let mut bm = HybridBitmap::new();
395+
for i in 100..110u64 {
396+
for v in i * 65536..i * 65536 + 5000 {
397+
bm.insert(v);
398+
}
399+
}
400+
for j in 110..150u64 {
401+
for v in j * 65536..j * 65536 + 100 {
402+
bm.insert(v);
403+
}
404+
}
405+
406+
bm
407+
}
408+
409+
fn small_bitmap() -> HybridBitmap {
410+
HybridBitmap::from_iter(24 * 65536..24 * 65536 + 31)
411+
}
412+
413+
fn overlap_small_bitmap() -> HybridBitmap {
414+
HybridBitmap::from_iter(24 * 65536 - 10..24 * 65536 + 21)
415+
}
416+
417+
fn subset_small_bitmap() -> HybridBitmap {
418+
HybridBitmap::from_iter(24 * 65536 + 1..24 * 65536 + 30)
419+
}
420+
421+
const C1: &[(&str, DataType)] = &[("a", DataType::Bitmap)];
422+
const C2: &[(&str, DataType)] = &[("a", DataType::Bitmap), ("b", DataType::Bitmap)];
423+
424+
#[divan::bench]
425+
fn bitmap_contains_large(bencher: divan::Bencher) {
426+
let bm = large_bitmap();
427+
let block = DataBlock::new(vec![bitmap_entry(&bm)], 1);
428+
let expr = build_expr("bitmap_contains(a, 5*65536+2500)", C1);
429+
bencher.bench(|| eval_block(&expr, &block));
430+
}
431+
432+
#[divan::bench]
433+
fn bitmap_contains_small(bencher: divan::Bencher) {
434+
let bm = small_bitmap();
435+
let block = DataBlock::new(vec![bitmap_entry(&bm)], 1);
436+
let expr = build_expr("bitmap_contains(a, 15)", C1);
437+
bencher.bench(|| eval_block(&expr, &block));
438+
}
439+
440+
#[divan::bench]
441+
fn bitmap_count_large(bencher: divan::Bencher) {
442+
let bm = large_bitmap();
443+
let block = DataBlock::new(vec![bitmap_entry(&bm)], 1);
444+
let expr = build_expr("bitmap_count(a)", C1);
445+
bencher.bench(|| eval_block(&expr, &block));
446+
}
447+
448+
#[divan::bench]
449+
fn bitmap_count_small(bencher: divan::Bencher) {
450+
let bm = small_bitmap();
451+
let block = DataBlock::new(vec![bitmap_entry(&bm)], 1);
452+
let expr = build_expr("bitmap_count(a)", C1);
453+
bencher.bench(|| eval_block(&expr, &block));
454+
}
455+
456+
// bitmap_min
457+
#[divan::bench]
458+
fn bitmap_min_large(bencher: divan::Bencher) {
459+
let bm = large_bitmap();
460+
let block = DataBlock::new(vec![bitmap_entry(&bm)], 1);
461+
let expr = build_expr("bitmap_min(a)", C1);
462+
bencher.bench(|| eval_block(&expr, &block));
463+
}
464+
465+
#[divan::bench]
466+
fn bitmap_min_small(bencher: divan::Bencher) {
467+
let bm = small_bitmap();
468+
let block = DataBlock::new(vec![bitmap_entry(&bm)], 1);
469+
let expr = build_expr("bitmap_min(a)", C1);
470+
bencher.bench(|| eval_block(&expr, &block));
471+
}
472+
473+
#[divan::bench]
474+
fn bitmap_max_large(bencher: divan::Bencher) {
475+
let bm = large_bitmap();
476+
let block = DataBlock::new(vec![bitmap_entry(&bm)], 1);
477+
let expr = build_expr("bitmap_max(a)", C1);
478+
bencher.bench(|| eval_block(&expr, &block));
479+
}
480+
481+
#[divan::bench]
482+
fn bitmap_max_small(bencher: divan::Bencher) {
483+
let bm = small_bitmap();
484+
let block = DataBlock::new(vec![bitmap_entry(&bm)], 1);
485+
let expr = build_expr("bitmap_max(a)", C1);
486+
bencher.bench(|| eval_block(&expr, &block));
487+
}
488+
489+
#[divan::bench]
490+
fn bitmap_and_large_large(bencher: divan::Bencher) {
491+
let a = large_bitmap();
492+
let b = overlap_large_bitmap();
493+
let block = DataBlock::new(vec![bitmap_entry(&a), bitmap_entry(&b)], 1);
494+
let expr = build_expr("bitmap_and(a, b)", C2);
495+
bencher.bench(|| eval_block(&expr, &block));
496+
}
497+
498+
#[divan::bench]
499+
fn bitmap_and_small_small(bencher: divan::Bencher) {
500+
let a = small_bitmap();
501+
let b = overlap_small_bitmap();
502+
let block = DataBlock::new(vec![bitmap_entry(&a), bitmap_entry(&b)], 1);
503+
let expr = build_expr("bitmap_and(a, b)", C2);
504+
bencher.bench(|| eval_block(&expr, &block));
505+
}
506+
507+
#[divan::bench]
508+
fn bitmap_and_large_small(bencher: divan::Bencher) {
509+
let a = large_bitmap();
510+
let b = small_bitmap();
511+
let block = DataBlock::new(vec![bitmap_entry(&a), bitmap_entry(&b)], 1);
512+
let expr = build_expr("bitmap_and(a, b)", C2);
513+
bencher.bench(|| eval_block(&expr, &block));
514+
}
515+
516+
#[divan::bench]
517+
fn bitmap_and_small_large(bencher: divan::Bencher) {
518+
let a = small_bitmap();
519+
let b = large_bitmap();
520+
let block = DataBlock::new(vec![bitmap_entry(&a), bitmap_entry(&b)], 1);
521+
let expr = build_expr("bitmap_and(a, b)", C2);
522+
bencher.bench(|| eval_block(&expr, &block));
523+
}
524+
525+
#[divan::bench]
526+
fn bitmap_has_any_large_large(bencher: divan::Bencher) {
527+
let a = large_bitmap();
528+
let b = overlap_large_bitmap();
529+
let block = DataBlock::new(vec![bitmap_entry(&a), bitmap_entry(&b)], 1);
530+
let expr = build_expr("bitmap_has_any(a, b)", C2);
531+
bencher.bench(|| eval_block(&expr, &block));
532+
}
533+
534+
#[divan::bench]
535+
fn bitmap_has_any_small_small(bencher: divan::Bencher) {
536+
let a = small_bitmap();
537+
let b = overlap_small_bitmap();
538+
let block = DataBlock::new(vec![bitmap_entry(&a), bitmap_entry(&b)], 1);
539+
let expr = build_expr("bitmap_has_any(a, b)", C2);
540+
bencher.bench(|| eval_block(&expr, &block));
541+
}
542+
543+
#[divan::bench]
544+
fn bitmap_has_any_large_small(bencher: divan::Bencher) {
545+
let a = large_bitmap();
546+
let b = small_bitmap();
547+
let block = DataBlock::new(vec![bitmap_entry(&a), bitmap_entry(&b)], 1);
548+
let expr = build_expr("bitmap_has_any(a, b)", C2);
549+
bencher.bench(|| eval_block(&expr, &block));
550+
}
551+
552+
#[divan::bench]
553+
fn bitmap_has_any_small_large(bencher: divan::Bencher) {
554+
let a = small_bitmap();
555+
let b = large_bitmap();
556+
let block = DataBlock::new(vec![bitmap_entry(&a), bitmap_entry(&b)], 1);
557+
let expr = build_expr("bitmap_has_any(a, b)", C2);
558+
bencher.bench(|| eval_block(&expr, &block));
559+
}
560+
561+
#[divan::bench]
562+
fn bitmap_has_any_large_large_disjoint(bencher: divan::Bencher) {
563+
let a = large_bitmap();
564+
let b = disjoint_large_bitmap();
565+
let block = DataBlock::new(vec![bitmap_entry(&a), bitmap_entry(&b)], 1);
566+
let expr = build_expr("bitmap_has_any(a, b)", C2);
567+
bencher.bench(|| eval_block(&expr, &block));
568+
}
569+
570+
#[divan::bench]
571+
fn bitmap_has_all_large_large(bencher: divan::Bencher) {
572+
let a = large_bitmap();
573+
let b = subset_large_bitmap();
574+
let block = DataBlock::new(vec![bitmap_entry(&a), bitmap_entry(&b)], 1);
575+
let expr = build_expr("bitmap_has_all(a, b)", C2);
576+
bencher.bench(|| eval_block(&expr, &block));
577+
}
578+
579+
#[divan::bench]
580+
fn bitmap_has_all_small_small(bencher: divan::Bencher) {
581+
let a = small_bitmap();
582+
let b = subset_small_bitmap();
583+
let block = DataBlock::new(vec![bitmap_entry(&a), bitmap_entry(&b)], 1);
584+
let expr = build_expr("bitmap_has_all(a, b)", C2);
585+
bencher.bench(|| eval_block(&expr, &block));
586+
}
587+
588+
#[divan::bench]
589+
fn bitmap_has_all_large_small(bencher: divan::Bencher) {
590+
let a = large_bitmap();
591+
let b = small_bitmap();
592+
let block = DataBlock::new(vec![bitmap_entry(&a), bitmap_entry(&b)], 1);
593+
let expr = build_expr("bitmap_has_all(a, b)", C2);
594+
bencher.bench(|| eval_block(&expr, &block));
595+
}
596+
597+
#[divan::bench]
598+
fn bitmap_has_all_small_large(bencher: divan::Bencher) {
599+
let a = small_bitmap();
600+
let b = large_bitmap();
601+
let block = DataBlock::new(vec![bitmap_entry(&a), bitmap_entry(&b)], 1);
602+
let expr = build_expr("bitmap_has_all(a, b)", C2);
603+
bencher.bench(|| eval_block(&expr, &block));
604+
}
605+
606+
#[divan::bench]
607+
fn bitmap_has_all_large_large_disjoint(bencher: divan::Bencher) {
608+
let a = large_bitmap();
609+
let b = disjoint_large_bitmap();
610+
let block = DataBlock::new(vec![bitmap_entry(&a), bitmap_entry(&b)], 1);
611+
let expr = build_expr("bitmap_has_all(a, b)", C2);
612+
bencher.bench(|| eval_block(&expr, &block));
613+
}
614+
}
615+
311616
#[divan::bench_group(max_time = 0.5)]
312617
mod datetime_fast_path {
313618
use std::sync::LazyLock;

0 commit comments

Comments
 (0)