use oxirs_rule::{
integration::{rule_builders, RuleIntegration},
performance::{PerformanceTestHarness, PerformanceThresholds, RuleEngineProfiler},
Rule, RuleAtom, RuleEngine, Term,
};
fn main() -> anyhow::Result<()> {
println!("🔍 OxiRS Rule Engine Performance Analysis Example");
println!("================================================");
basic_profiling_example()?;
comprehensive_testing_example()?;
memory_stress_testing_example()?;
integration_performance_example()?;
Ok(())
}
fn basic_profiling_example() -> anyhow::Result<()> {
println!("\n📊 Example 1: Basic Performance Profiling");
println!("-----------------------------------------");
let mut profiler = RuleEngineProfiler::new();
let rules = vec![
Rule {
name: "basic_rule_1".to_string(),
body: vec![RuleAtom::Triple {
subject: Term::Variable("X".to_string()),
predicate: Term::Constant("hasType".to_string()),
object: Term::Constant("Person".to_string()),
}],
head: vec![RuleAtom::Triple {
subject: Term::Variable("X".to_string()),
predicate: Term::Constant("hasProperty".to_string()),
object: Term::Constant("intelligent".to_string()),
}],
},
Rule {
name: "basic_rule_2".to_string(),
body: vec![
RuleAtom::Triple {
subject: Term::Variable("X".to_string()),
predicate: Term::Constant("hasProperty".to_string()),
object: Term::Constant("intelligent".to_string()),
},
RuleAtom::Triple {
subject: Term::Variable("X".to_string()),
predicate: Term::Constant("hasAge".to_string()),
object: Term::Variable("Age".to_string()),
},
],
head: vec![RuleAtom::Triple {
subject: Term::Variable("X".to_string()),
predicate: Term::Constant("isQualified".to_string()),
object: Term::Constant("true".to_string()),
}],
},
];
let facts = generate_test_facts(100);
let mut engine = RuleEngine::new();
profiler.profile_operation("rule_loading", || {
for rule in rules {
engine.add_rule(rule);
}
});
profiler.profile_operation("fact_processing", || {
engine.add_facts(facts.clone());
});
let _results = profiler.profile_operation("forward_chaining", || {
engine.forward_chain(&facts).unwrap_or_default()
});
profiler.print_report();
Ok(())
}
fn comprehensive_testing_example() -> anyhow::Result<()> {
println!("\n🧪 Example 2: Comprehensive Performance Testing");
println!("-----------------------------------------------");
let mut harness = PerformanceTestHarness::new();
let test_cases = vec![
(50, 5, "Small scale"),
(200, 10, "Medium scale"),
(500, 15, "Large scale"),
];
for (fact_count, rule_count, description) in test_cases {
println!("\n🔬 Testing {description}: {fact_count} facts, {rule_count} rules");
let facts = generate_test_facts(fact_count);
let rules = generate_test_rules(rule_count);
let metrics = harness.run_comprehensive_test(rules, facts);
println!(" Total time: {:?}", metrics.total_time);
println!(" Rules processed: {}", metrics.rules_processed);
println!(" Facts processed: {}", metrics.facts_processed);
println!(" Inferred facts: {}", metrics.inferred_facts);
println!(
" Peak memory: {} bytes",
metrics.memory_stats.peak_memory_usage
);
if !metrics.warnings.is_empty() {
println!(" ⚠️ Warnings: {}", metrics.warnings.len());
}
}
Ok(())
}
fn memory_stress_testing_example() -> anyhow::Result<()> {
println!("\n💾 Example 3: Memory Stress Testing");
println!("-----------------------------------");
let mut harness = PerformanceTestHarness::new();
let stress_levels = vec![1, 2, 5];
for scale in stress_levels {
println!("\n🧠 Memory stress test - Scale factor: {scale}");
let metrics = harness.run_memory_stress_test(scale);
println!(" Total time: {:?}", metrics.total_time);
println!(
" Peak memory: {} MB",
metrics.memory_stats.peak_memory_usage / (1024 * 1024)
);
println!(
" Facts memory: {} KB",
metrics.memory_stats.facts_memory / 1024
);
println!(
" Rules memory: {} KB",
metrics.memory_stats.rules_memory / 1024
);
if metrics.memory_stats.peak_memory_usage > 100 * 1024 * 1024 {
println!(" ⚠️ High memory usage detected");
}
}
Ok(())
}
fn integration_performance_example() -> anyhow::Result<()> {
println!("\n🔗 Example 4: Integration Performance Testing");
println!("---------------------------------------------");
let custom_thresholds = PerformanceThresholds {
max_rule_loading_time: 500, max_forward_chaining_time: 2000, max_backward_chaining_time: 1000, max_memory_usage: 512, max_iterations: 500,
};
let mut profiler = RuleEngineProfiler::with_thresholds(custom_thresholds);
let integration_result = profiler.profile_operation("integration_test", || {
let mut integration = RuleIntegration::new();
integration.add_rules(rule_builders::all_rdfs_rules());
for i in 0..200 {
let subject_iri = format!("http://example.org/person{i}");
let subject = oxirs_core::NamedNode::new(&subject_iri).unwrap();
let predicate =
oxirs_core::NamedNode::new("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")
.unwrap();
let object = oxirs_core::NamedNode::new("http://example.org/Person").unwrap();
let triple = oxirs_core::Triple::new(subject, predicate, object);
integration.store.insert_triple(triple).unwrap();
}
integration.apply_rules().unwrap()
});
println!("Integration test derived {integration_result} facts");
let metrics = profiler.generate_report();
if let Ok(json_report) = profiler.export_json() {
println!("\n📄 JSON report (first 500 chars):");
println!("{}", &json_report[..json_report.len().min(500)]);
if json_report.len() > 500 {
println!("... (truncated)");
}
}
if !metrics.warnings.is_empty() {
println!("\n⚠️ Performance Warnings:");
for warning in &metrics.warnings {
println!(" - {warning}");
}
} else {
println!("\n✅ All performance thresholds met!");
}
Ok(())
}
fn generate_test_facts(count: usize) -> Vec<RuleAtom> {
let mut facts = Vec::with_capacity(count);
for i in 0..count {
facts.push(RuleAtom::Triple {
subject: Term::Constant(format!("person_{i}")),
predicate: Term::Constant("hasType".to_string()),
object: Term::Constant("Person".to_string()),
});
facts.push(RuleAtom::Triple {
subject: Term::Constant(format!("person_{i}")),
predicate: Term::Constant("hasAge".to_string()),
object: Term::Literal((20 + i % 50).to_string()),
});
if i % 3 == 0 {
facts.push(RuleAtom::Triple {
subject: Term::Constant(format!("person_{i}")),
predicate: Term::Constant("hasEducation".to_string()),
object: Term::Constant("university".to_string()),
});
}
}
facts
}
fn generate_test_rules(count: usize) -> Vec<Rule> {
let mut rules = Vec::with_capacity(count);
for i in 0..count {
rules.push(Rule {
name: format!("test_rule_{i}"),
body: vec![RuleAtom::Triple {
subject: Term::Variable("X".to_string()),
predicate: Term::Constant("hasType".to_string()),
object: Term::Constant("Person".to_string()),
}],
head: vec![RuleAtom::Triple {
subject: Term::Variable("X".to_string()),
predicate: Term::Constant("hasProperty".to_string()),
object: Term::Constant(format!("property_{i}")),
}],
});
}
rules.extend(rule_builders::all_rdfs_rules());
rules
}