extern crate time; extern crate simple_parallel; extern crate parry; use parry::{Expression}; use time::Duration; use std::cmp; fn naive(a: &[f64], b: &[f64]) -> Vec { let na = a.len(); let nb = b.len(); let nc = na + nb - 1; let mut v = vec![0.0; nc]; for (k, place) in v.iter_mut().enumerate() { let lo_j = if k + 1 > nb { k - nb + 1 } else { 0 }; let hi_j = cmp::min(k + 1, na); let slice_a = &a[lo_j..hi_j]; let slice_b = &b[(k + 1) - hi_j..k - lo_j +1]; *place = slice_a.iter().zip(slice_b.iter().rev()).fold(0.0, |a, (&x, &y)| a + x * y); } v } fn sp(a: &[f64], b: &[f64]) -> Vec { let na = a.len(); let nb = b.len(); let nc = na + nb - 1; let mut v = vec![0.0; nc]; simple_parallel::Pool::new(8).for_(v.iter_mut().enumerate(), |(k, place)| { let lo_j = if k + 1 > nb { k - nb + 1 } else { 0 }; let hi_j = cmp::min(k + 1, na); let slice_a = &a[lo_j..hi_j]; let slice_b = &b[(k + 1) - hi_j..k - lo_j +1]; *place = slice_a.iter().zip(slice_b.iter().rev()).fold(0.0, |a, (&x, &y)| a + x * y); }); v } fn p(a: &[f64], b: &[f64]) -> Vec { let na = a.len(); let nb = b.len(); let nc = na + nb - 1; let mut v = vec![0.0; nc]; for (k, place) in v.iter_mut().enumerate() { let lo_j = if k + 1 > nb { k - nb + 1 } else { 0 }; let hi_j = cmp::min(k + 1, na); let slice_a = &a[lo_j..hi_j]; let slice_b = &b[(k + 1) - hi_j..k - lo_j +1]; *place = (slice_b.rev() * slice_a).sum(); } v } fn measure T>(name: &str, mut f: F) { let time = Duration::span(|| { f(); }); let secs = time.num_nanoseconds().unwrap() as f64 * 1e-9; println!("{}: {:.3}s", name, secs); } fn main() { let vec = vec![1.0; 20_000]; measure("naive", || naive(&vec, &vec)); measure("simple_parallel", || sp(&vec, &vec)); measure("parry", || p(&vec, &vec)); }