use taskflow_rs::{Executor, Taskflow};
use std::sync::{Arc, atomic::{AtomicUsize, Ordering}};
use std::time::Instant;
fn main() {
println!("=== Parallel run_n Demo ===\n");
demo_sequential_vs_parallel();
println!();
demo_parallel_instances();
println!();
demo_run_until();
println!();
demo_real_world_batch();
}
fn demo_sequential_vs_parallel() {
println!("1. Sequential vs Parallel Execution");
println!(" Compare performance of sequential and parallel runs\n");
let mut executor = Executor::new(4);
println!(" Sequential (run_n_sequential):");
let start = Instant::now();
executor.run_n_sequential(5, || {
let mut taskflow = Taskflow::new();
taskflow.emplace(|| {
std::thread::sleep(std::time::Duration::from_millis(100));
});
taskflow
}).wait();
let sequential_time = start.elapsed();
println!(" Time: {:?}", sequential_time);
println!("\n Parallel (run_n):");
let start = Instant::now();
executor.run_n(5, || {
let mut taskflow = Taskflow::new();
taskflow.emplace(|| {
std::thread::sleep(std::time::Duration::from_millis(100));
});
taskflow
}).wait();
let parallel_time = start.elapsed();
println!(" Time: {:?}", parallel_time);
println!("\n Speedup: {:.2}x", sequential_time.as_millis() as f64 / parallel_time.as_millis() as f64);
println!(" ✓ Parallel execution is faster");
}
fn demo_parallel_instances() {
println!("2. Parallel Instances");
println!(" Run multiple instances with shared state\n");
let mut executor = Executor::new(4);
let counter = Arc::new(AtomicUsize::new(0));
let results = Arc::new(std::sync::Mutex::new(Vec::new()));
println!(" Running 10 instances in parallel:");
let c = counter.clone();
let r = results.clone();
executor.run_n(10, move || {
let c = c.clone();
let r = r.clone();
let mut taskflow = Taskflow::new();
taskflow.emplace(move || {
let id = c.fetch_add(1, Ordering::Relaxed);
println!(" [Instance {}] Executing", id);
std::thread::sleep(std::time::Duration::from_millis(50));
r.lock().unwrap().push(id);
});
taskflow
}).wait();
let final_count = counter.load(Ordering::Relaxed);
let results = results.lock().unwrap();
println!("\n Total executions: {}", final_count);
println!(" Results collected: {}", results.len());
assert_eq!(final_count, 10);
assert_eq!(results.len(), 10);
println!(" ✓ All instances executed correctly");
}
fn demo_run_until() {
println!("3. Run Until Condition");
println!(" Execute until a condition is met\n");
let mut executor = Executor::new(4);
let sum = Arc::new(AtomicUsize::new(0));
let target = 100;
println!(" Target sum: {}", target);
println!(" Executing...");
let s = sum.clone();
executor.run_until(
move || {
let s = s.clone();
let mut taskflow = Taskflow::new();
taskflow.emplace(move || {
let value = 7; let new_sum = s.fetch_add(value, Ordering::Relaxed) + value;
println!(" Added {}, sum = {}", value, new_sum);
});
taskflow
},
|| sum.load(Ordering::Relaxed) >= target
).wait();
let final_sum = sum.load(Ordering::Relaxed);
println!("\n Final sum: {}", final_sum);
assert!(final_sum >= target);
println!(" ✓ Condition met");
}
fn demo_real_world_batch() {
println!("4. Real-World Batch Processing");
println!(" Process multiple batches in parallel\n");
let mut executor = Executor::new(4);
let processed_items = Arc::new(AtomicUsize::new(0));
println!(" Processing 5 batches with 10 items each:");
let p = processed_items.clone();
executor.run_n(5, move || {
let p = p.clone();
let mut taskflow = Taskflow::new();
let p1 = p.clone();
let load = taskflow.emplace(move || {
println!(" [Batch] Loading data...");
std::thread::sleep(std::time::Duration::from_millis(20));
});
let p2 = p.clone();
let process = taskflow.emplace(move || {
println!(" [Batch] Processing...");
for _ in 0..10 {
p2.fetch_add(1, Ordering::Relaxed);
std::thread::sleep(std::time::Duration::from_millis(5));
}
});
let p3 = p.clone();
let save = taskflow.emplace(move || {
println!(" [Batch] Saving results...");
std::thread::sleep(std::time::Duration::from_millis(20));
});
load.precede(&process);
process.precede(&save);
taskflow
}).wait();
let total_processed = processed_items.load(Ordering::Relaxed);
println!("\n Total items processed: {}", total_processed);
assert_eq!(total_processed, 50); println!(" ✓ Batch processing complete");
}