1+ use criterion:: { criterion_group, criterion_main, Criterion } ;
2+ use deep_causality_uncertain:: { Uncertain , with_global_cache, SampledValue } ;
3+
4+ // --- Sampling Performance Benchmarks ---
5+
6+ fn bench_sampling_point ( c : & mut Criterion ) {
7+ let uncertain = Uncertain :: < f64 > :: point ( 10.0 ) ;
8+ c. bench_function ( "sampling_point" , |b| {
9+ b. iter ( || uncertain. sample ( ) . unwrap ( ) ) ;
10+ } ) ;
11+ }
12+
13+ fn bench_sampling_normal ( c : & mut Criterion ) {
14+ let uncertain = Uncertain :: < f64 > :: normal ( 10.0 , 2.0 ) ;
15+ c. bench_function ( "sampling_normal" , |b| {
16+ b. iter ( || uncertain. sample ( ) . unwrap ( ) ) ;
17+ } ) ;
18+ }
19+
20+ fn bench_sampling_bernoulli ( c : & mut Criterion ) {
21+ let uncertain = Uncertain :: < bool > :: bernoulli ( 0.5 ) ;
22+ c. bench_function ( "sampling_bernoulli" , |b| {
23+ b. iter ( || uncertain. sample ( ) . unwrap ( ) ) ;
24+ } ) ;
25+ }
26+
27+ // Benchmark for a simple arithmetic chain
28+ fn bench_sampling_arithmetic_chain ( c : & mut Criterion ) {
29+ let a = Uncertain :: < f64 > :: normal ( 10.0 , 1.0 ) ;
30+ let b = Uncertain :: < f64 > :: normal ( 5.0 , 0.5 ) ;
31+ let c_val = Uncertain :: < f64 > :: normal ( 2.0 , 0.1 ) ;
32+ let d = ( a + b) * c_val; // (Normal + Normal) * Normal
33+
34+ c. bench_function ( "sampling_arithmetic_chain" , |b| {
35+ b. iter ( || d. sample ( ) . unwrap ( ) ) ;
36+ } ) ;
37+ }
38+
39+ // Benchmark for a conditional operation
40+ fn bench_sampling_conditional ( c : & mut Criterion ) {
41+ let condition = Uncertain :: < bool > :: bernoulli ( 0.5 ) ;
42+ let if_true = Uncertain :: < f64 > :: normal ( 100.0 , 10.0 ) ;
43+ let if_false = Uncertain :: < f64 > :: normal ( 200.0 , 20.0 ) ;
44+ let result = Uncertain :: conditional ( condition, if_true, if_false) ;
45+
46+ c. bench_function ( "sampling_conditional" , |b| {
47+ b. iter ( || result. sample ( ) . unwrap ( ) ) ;
48+ } ) ;
49+ }
50+
51+ // --- Operator Overhead Benchmarks (Graph Construction) ---
52+
53+ // Benchmark for simple f64 addition (baseline)
54+ fn bench_f64_add_baseline ( c : & mut Criterion ) {
55+ let x = 10.0 ;
56+ let y = 5.0 ;
57+ c. bench_function ( "f64_add_baseline" , |b| {
58+ b. iter ( || x + y) ;
59+ } ) ;
60+ }
61+
62+ // Benchmark for Uncertain<f64> addition (graph construction only)
63+ fn bench_uncertain_f64_add_graph_construction ( c : & mut Criterion ) {
64+ let a = Uncertain :: < f64 > :: point ( 10.0 ) ;
65+ let b = Uncertain :: < f64 > :: point ( 5.0 ) ;
66+ c. bench_function ( "uncertain_f64_add_graph_construction" , |bencher| {
67+ bencher. iter ( || {
68+ let cloned_a = a. clone ( ) ;
69+ let cloned_b = b. clone ( ) ;
70+ let _ = cloned_a + cloned_b;
71+ } ) ;
72+ } ) ;
73+ }
74+
75+ // Benchmark for map operation (graph construction only)
76+ fn bench_uncertain_f64_map_graph_construction ( c : & mut Criterion ) {
77+ let uncertain = Uncertain :: < f64 > :: point ( 10.0 ) ;
78+ c. bench_function ( "uncertain_f64_map_graph_construction" , |b| {
79+ b. iter ( || {
80+ let _ = uncertain. clone ( ) . map ( |x| x * 2.0 ) ;
81+ } ) ;
82+ } ) ;
83+ }
84+
85+ // --- Combined Benchmarks (Graph Construction + Sampling) ---
86+
87+ // Benchmark for a simple arithmetic operation including sampling
88+ fn bench_uncertain_f64_add_and_sample ( c : & mut Criterion ) {
89+ let a = Uncertain :: < f64 > :: normal ( 10.0 , 1.0 ) ;
90+ let b = Uncertain :: < f64 > :: normal ( 5.0 , 0.5 ) ;
91+ c. bench_function ( "uncertain_f64_add_and_sample" , |bencher| {
92+ bencher. iter ( || {
93+ let cloned_a = a. clone ( ) ;
94+ let cloned_b = b. clone ( ) ;
95+ let sum = cloned_a + cloned_b;
96+ sum. sample ( ) . unwrap ( ) ;
97+ } ) ;
98+ } ) ;
99+ }
100+
101+ // Benchmark for a complex chain including sampling
102+ fn bench_complex_chain_and_sample ( c : & mut Criterion ) {
103+ let s1 = Uncertain :: < f64 > :: normal ( 50.0 , 2.0 ) ;
104+ let s2 = Uncertain :: < f64 > :: normal ( 52.0 , 1.5 ) ;
105+ let s3 = Uncertain :: < f64 > :: normal ( 48.0 , 1.0 ) ;
106+
107+ let combined_reading = ( s1 + s2 + s3) / Uncertain :: < f64 > :: point ( 3.0 ) ;
108+ let is_high = combined_reading. greater_than ( 51.0 ) ;
109+ let final_decision = Uncertain :: conditional (
110+ is_high,
111+ Uncertain :: < f64 > :: point ( 1.0 ) ,
112+ Uncertain :: < f64 > :: point ( 0.0 ) ,
113+ ) ;
114+
115+ c. bench_function ( "complex_chain_and_sample" , |b| {
116+ b. iter ( || {
117+ final_decision. sample ( ) . unwrap ( ) ;
118+ } ) ;
119+ } ) ;
120+ }
121+
122+ // --- Cache Effect Benchmarks ---
123+
124+ // Benchmark sampling with cache hits
125+ fn bench_sampling_with_cache_hits ( c : & mut Criterion ) {
126+ let uncertain = Uncertain :: < f64 > :: normal ( 10.0 , 1.0 ) ;
127+ let _id = uncertain. id ( ) ;
128+ let sample_index_to_hit = 0 ; // Always hit this index
129+
130+ // Pre-populate the cache once before the benchmark loop
131+ with_global_cache ( |cache| {
132+ cache. clear ( ) ; // Clear once to ensure a clean state
133+ cache. insert ( ( _id, sample_index_to_hit) , SampledValue :: Float ( 42.0 ) ) ;
134+ } ) ;
135+
136+ c. bench_function ( "sampling_with_cache_hits" , |b| {
137+ b. iter ( || {
138+ let _ = uncertain. sample_with_index ( sample_index_to_hit) . unwrap ( ) ;
139+ } ) ;
140+ } ) ;
141+ }
142+
143+ // Benchmark sampling with cache misses (always recomputing)
144+ fn bench_sampling_with_cache_misses ( c : & mut Criterion ) {
145+ let uncertain = Uncertain :: < f64 > :: normal ( 10.0 , 1.0 ) ;
146+ let _id = uncertain. id ( ) ;
147+
148+ // Clear the cache once before the benchmark loop
149+ with_global_cache ( |cache| {
150+ cache. clear ( ) ;
151+ } ) ;
152+
153+ c. bench_function ( "sampling_with_cache_misses" , |b| {
154+ let mut i = 0 ; // Use a new, unique index for each iteration
155+ b. iter ( || {
156+ let _ = uncertain. sample_with_index ( i) . unwrap ( ) ;
157+ i += 1 ; // Increment index for next iteration to ensure a miss
158+ } ) ;
159+ } ) ;
160+ }
161+
162+ criterion_group ! (
163+ benches,
164+ bench_sampling_point,
165+ bench_sampling_normal,
166+ bench_sampling_bernoulli,
167+ bench_sampling_arithmetic_chain,
168+ bench_sampling_conditional,
169+ bench_f64_add_baseline,
170+ bench_uncertain_f64_add_graph_construction,
171+ bench_uncertain_f64_map_graph_construction,
172+ bench_uncertain_f64_add_and_sample,
173+ bench_complex_chain_and_sample,
174+ bench_sampling_with_cache_hits,
175+ bench_sampling_with_cache_misses,
176+ ) ;
177+ criterion_main ! ( benches) ;
0 commit comments