@@ -8,6 +8,7 @@ use query_engine_rust::data_model::{
88 StreamingConfig ,
99} ;
1010use query_engine_rust:: precompute_operators:: sum_accumulator:: SumAccumulator ;
11+ use query_engine_rust:: stores:: simple_map_store:: per_key_legacy:: LegacySimpleMapStorePerKey ;
1112use query_engine_rust:: stores:: simple_map_store:: SimpleMapStore ;
1213use query_engine_rust:: stores:: Store ;
1314use sketch_db_common:: aggregation_config:: AggregationConfig ;
@@ -834,6 +835,266 @@ fn bench_multi_agg_id(c: &mut Criterion) {
834835 group. finish ( ) ;
835836}
836837
838+ // ---------------------------------------------------------------------------
839+ // Legacy store helpers — use the real deprecated LegacySimpleMapStorePerKey
840+ // ---------------------------------------------------------------------------
841+
842+ #[ allow( deprecated) ]
843+ fn build_legacy_store ( time_ranges : usize , labels : usize ) -> LegacySimpleMapStorePerKey {
844+ let config = make_streaming_config ( ) ;
845+ let store = LegacySimpleMapStorePerKey :: new ( config, CleanupPolicy :: NoCleanup ) ;
846+ for i in 0 ..time_ranges {
847+ let start = ( i as u64 ) * 1000 ;
848+ let end = start + 1000 ;
849+ for j in 0 ..labels {
850+ let key = KeyByLabelValues :: new_with_labels ( vec ! [ format!( "host-{j}" ) ] ) ;
851+ let output = PrecomputedOutput :: new ( start, end, Some ( key) , 1 ) ;
852+ let acc: Box < dyn AggregateCore > = Box :: new ( SumAccumulator :: with_sum ( 1.0 ) ) ;
853+ store. insert_precomputed_output ( output, acc) . unwrap ( ) ;
854+ }
855+ }
856+ store
857+ }
858+
859+ // ---------------------------------------------------------------------------
860+ // Old vs New comparison benchmarks
861+ // ---------------------------------------------------------------------------
862+
863+ #[ allow( deprecated) ]
864+ fn bench_old_vs_new_insert ( c : & mut Criterion ) {
865+ let mut group = c. benchmark_group ( "old_vs_new/insert" ) ;
866+
867+ for & ( time_ranges, labels) in & [ ( 10usize , 10usize ) , ( 100 , 10 ) , ( 1000 , 10 ) ] {
868+ let total = time_ranges * labels;
869+
870+ group. bench_with_input (
871+ BenchmarkId :: new ( "legacy" , total) ,
872+ & ( time_ranges, labels) ,
873+ |b, & ( tr, l) | {
874+ b. iter ( || {
875+ black_box ( build_legacy_store ( black_box ( tr) , black_box ( l) ) ) ;
876+ } ) ;
877+ } ,
878+ ) ;
879+
880+ group. bench_with_input (
881+ BenchmarkId :: new ( "new" , total) ,
882+ & ( time_ranges, labels) ,
883+ |b, & ( tr, l) | {
884+ b. iter ( || {
885+ black_box ( build_populated_store ( black_box ( tr) , black_box ( l) ) ) ;
886+ } ) ;
887+ } ,
888+ ) ;
889+ }
890+
891+ group. finish ( ) ;
892+ }
893+
894+ #[ allow( deprecated) ]
895+ fn bench_old_vs_new_range_query ( c : & mut Criterion ) {
896+ let mut group = c. benchmark_group ( "old_vs_new/range_query" ) ;
897+ let time_ranges = 1_000 ;
898+ let query_start = 0u64 ;
899+ let query_end = ( time_ranges as u64 ) * 1000 / 10 ;
900+
901+ for labels in [ 1 , 10 , 100 ] {
902+ {
903+ let store = build_legacy_store ( time_ranges, labels) ;
904+ group. bench_with_input ( BenchmarkId :: new ( "legacy" , labels) , & labels, |b, _| {
905+ b. iter ( || {
906+ black_box (
907+ store
908+ . query_precomputed_output (
909+ black_box ( "test_metric" ) ,
910+ black_box ( 1 ) ,
911+ black_box ( query_start) ,
912+ black_box ( query_end) ,
913+ )
914+ . unwrap ( ) ,
915+ )
916+ } ) ;
917+ } ) ;
918+ }
919+ {
920+ let store = build_populated_store ( time_ranges, labels) ;
921+ group. bench_with_input ( BenchmarkId :: new ( "new" , labels) , & labels, |b, _| {
922+ b. iter ( || {
923+ black_box (
924+ store
925+ . query_precomputed_output (
926+ black_box ( "test_metric" ) ,
927+ black_box ( 1 ) ,
928+ black_box ( query_start) ,
929+ black_box ( query_end) ,
930+ )
931+ . unwrap ( ) ,
932+ )
933+ } ) ;
934+ } ) ;
935+ }
936+ }
937+
938+ group. finish ( ) ;
939+ }
940+
941+ #[ allow( deprecated) ]
942+ fn bench_old_vs_new_exact_query ( c : & mut Criterion ) {
943+ let mut group = c. benchmark_group ( "old_vs_new/exact_query" ) ;
944+ let time_ranges = 1_000 ;
945+ let mid = ( time_ranges / 2 ) as u64 ;
946+ let exact_start = mid * 1000 ;
947+ let exact_end = exact_start + 1000 ;
948+
949+ for labels in [ 1 , 10 , 100 ] {
950+ {
951+ let store = build_legacy_store ( time_ranges, labels) ;
952+ group. bench_with_input ( BenchmarkId :: new ( "legacy" , labels) , & labels, |b, _| {
953+ b. iter ( || {
954+ black_box (
955+ store
956+ . query_precomputed_output_exact (
957+ black_box ( "test_metric" ) ,
958+ black_box ( 1 ) ,
959+ black_box ( exact_start) ,
960+ black_box ( exact_end) ,
961+ )
962+ . unwrap ( ) ,
963+ )
964+ } ) ;
965+ } ) ;
966+ }
967+ {
968+ let store = build_populated_store ( time_ranges, labels) ;
969+ group. bench_with_input ( BenchmarkId :: new ( "new" , labels) , & labels, |b, _| {
970+ b. iter ( || {
971+ black_box (
972+ store
973+ . query_precomputed_output_exact (
974+ black_box ( "test_metric" ) ,
975+ black_box ( 1 ) ,
976+ black_box ( exact_start) ,
977+ black_box ( exact_end) ,
978+ )
979+ . unwrap ( ) ,
980+ )
981+ } ) ;
982+ } ) ;
983+ }
984+ }
985+
986+ group. finish ( ) ;
987+ }
988+
989+ #[ allow( deprecated) ]
990+ fn bench_old_vs_new_concurrent_reads ( c : & mut Criterion ) {
991+ let mut group = c. benchmark_group ( "old_vs_new/concurrent_reads" ) ;
992+ let time_ranges = 1_000 ;
993+ let labels = 10 ;
994+ let query_end = ( time_ranges as u64 ) * 1000 / 10 ;
995+ let num_threads = 4 ;
996+ let queries_per_thread = 20 ;
997+
998+ // Legacy — write lock on every query serialises all concurrent reads
999+ {
1000+ let store = Arc :: new ( build_legacy_store ( time_ranges, labels) ) ;
1001+ group. bench_function ( "legacy" , |b| {
1002+ b. iter ( || {
1003+ let barrier = Arc :: new ( Barrier :: new ( num_threads) ) ;
1004+ std:: thread:: scope ( |s| {
1005+ for _ in 0 ..num_threads {
1006+ let store_ref = Arc :: clone ( & store) ;
1007+ let barrier_ref = barrier. clone ( ) ;
1008+ s. spawn ( move || {
1009+ barrier_ref. wait ( ) ;
1010+ for _ in 0 ..queries_per_thread {
1011+ black_box (
1012+ store_ref
1013+ . query_precomputed_output ( "test_metric" , 1 , 0 , query_end)
1014+ . unwrap ( ) ,
1015+ ) ;
1016+ }
1017+ } ) ;
1018+ }
1019+ } ) ;
1020+ } ) ;
1021+ } ) ;
1022+ }
1023+
1024+ // New — shared read lock per agg_id allows true concurrency
1025+ {
1026+ let store = Arc :: new ( build_populated_store ( time_ranges, labels) ) ;
1027+ group. bench_function ( "new" , |b| {
1028+ b. iter ( || {
1029+ let barrier = Arc :: new ( Barrier :: new ( num_threads) ) ;
1030+ std:: thread:: scope ( |s| {
1031+ for _ in 0 ..num_threads {
1032+ let store_ref = Arc :: clone ( & store) ;
1033+ let barrier_ref = barrier. clone ( ) ;
1034+ s. spawn ( move || {
1035+ barrier_ref. wait ( ) ;
1036+ for _ in 0 ..queries_per_thread {
1037+ black_box (
1038+ store_ref
1039+ . query_precomputed_output ( "test_metric" , 1 , 0 , query_end)
1040+ . unwrap ( ) ,
1041+ ) ;
1042+ }
1043+ } ) ;
1044+ }
1045+ } ) ;
1046+ } ) ;
1047+ } ) ;
1048+ }
1049+
1050+ group. finish ( ) ;
1051+ }
1052+
1053+ #[ allow( deprecated) ]
1054+ fn bench_old_vs_new_scaling ( c : & mut Criterion ) {
1055+ let mut group = c. benchmark_group ( "old_vs_new/scaling" ) ;
1056+ let labels = 10 ;
1057+
1058+ for time_ranges in [ 100usize , 1_000 , 10_000 ] {
1059+ let query_end = ( time_ranges as u64 ) * 1000 / 10 ;
1060+
1061+ {
1062+ let store = build_legacy_store ( time_ranges, labels) ;
1063+ group. bench_with_input (
1064+ BenchmarkId :: new ( "legacy" , time_ranges) ,
1065+ & time_ranges,
1066+ |b, _| {
1067+ b. iter ( || {
1068+ black_box (
1069+ store
1070+ . query_precomputed_output ( "test_metric" , 1 , 0 , query_end)
1071+ . unwrap ( ) ,
1072+ )
1073+ } ) ;
1074+ } ,
1075+ ) ;
1076+ }
1077+ {
1078+ let store = build_populated_store ( time_ranges, labels) ;
1079+ group. bench_with_input (
1080+ BenchmarkId :: new ( "new" , time_ranges) ,
1081+ & time_ranges,
1082+ |b, _| {
1083+ b. iter ( || {
1084+ black_box (
1085+ store
1086+ . query_precomputed_output ( "test_metric" , 1 , 0 , query_end)
1087+ . unwrap ( ) ,
1088+ )
1089+ } ) ;
1090+ } ,
1091+ ) ;
1092+ }
1093+ }
1094+
1095+ group. finish ( ) ;
1096+ }
1097+
8371098criterion_group ! (
8381099 benches,
8391100 bench_insert,
@@ -848,5 +1109,10 @@ criterion_group!(
8481109 bench_query_patterns,
8491110 bench_high_label_cardinality,
8501111 bench_multi_agg_id,
1112+ bench_old_vs_new_insert,
1113+ bench_old_vs_new_range_query,
1114+ bench_old_vs_new_exact_query,
1115+ bench_old_vs_new_concurrent_reads,
1116+ bench_old_vs_new_scaling,
8511117) ;
8521118criterion_main ! ( benches) ;
0 commit comments