Skip to content

Commit eb312f7

Browse files
committed
test(deep_causality_uncertain): Added benchmarks.
Signed-off-by: Marvin Hansen <[email protected]>
1 parent ab767a0 commit eb312f7

File tree

4 files changed

+185
-2
lines changed

4 files changed

+185
-2
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

deep_causality/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ name = "deep_causality"
66
version = "0.9.0"
77
edition = "2021"
88
rust-version = "1.80"
9-
readme = "../README.md"
9+
readme = "../deep_causality_uncertain/README.md"
1010
license = "MIT"
1111

1212
description = "Computational causality library. Provides causality graph, collections, context and causal reasoning."

deep_causality_uncertain/Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,9 @@ parallel = ["dep:rayon"]
3636
all-features = true
3737

3838
[dev-dependencies]
39-
rusty-fork = "0.3.0"
39+
rusty-fork = "0.3.0"
40+
criterion = { version = "0.7.0", features = ["html_reports"] }
41+
42+
[[bench]]
43+
name = "uncertain_benchmarks"
44+
harness = false
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
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

Comments
 (0)