From fd82c716522f3ceced1bfd100a57ecf4c539aac9 Mon Sep 17 00:00:00 2001 From: Simon Gardling Date: Wed, 23 Mar 2022 20:41:24 -0400 Subject: [PATCH] use rayon parallel iterator when not on wasm --- Cargo.toml | 1 + src/function.rs | 34 +++++++++++----------------------- src/misc.rs | 14 ++++++++++++++ 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 218322b..69b5a59 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,7 @@ command-run = "1.1.1" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] instant = { version = "0.1.12" } tracing-subscriber = "0.3.9" +rayon = { git = "https://github.com/rayon-rs/rayon.git" } [target.'cfg(target_arch = "wasm32")'.dependencies] instant = { version = "0.1.12", features = ["wasm-bindgen"] } diff --git a/src/function.rs b/src/function.rs index a412398..f8726bf 100644 --- a/src/function.rs +++ b/src/function.rs @@ -2,7 +2,7 @@ use crate::egui_app::AppSettings; use crate::function_output::FunctionOutput; -use crate::misc::{newtons_method, resolution_helper, step_helper, SteppedVector}; +use crate::misc::{dyn_iter, newtons_method, resolution_helper, step_helper, SteppedVector}; use crate::parsing::BackingFunction; use eframe::{egui, epaint}; use egui::{ @@ -12,6 +12,9 @@ use egui::{ use epaint::Color32; use std::fmt::{self, Debug}; +#[cfg(not(target_arch = "wasm32"))] +use rayon::iter::ParallelIterator; + /// Represents the possible variations of Riemann Sums #[derive(PartialEq, Debug, Copy, Clone)] pub enum RiemannSum { @@ -98,13 +101,8 @@ impl FunctionEntry { let step = (integral_min_x - integral_max_x).abs() / (integral_num as f64); - let mut area: f64 = 0.0; - let mut i: usize = 0; - let data2: Vec<(f64, f64)> = (step_helper(integral_num, integral_min_x, step)) - .iter() + let data2: Vec<(f64, f64)> = dyn_iter(&step_helper(integral_num, integral_min_x, step)) .map(|x| { - i += 1; - let step_offset = step * x.signum(); // store the offset here so it doesn't have to be calculated multiple times let x2: f64 = x + step_offset; @@ -121,15 +119,11 @@ impl FunctionEntry { } }; - if !y.is_nan() { - area += y * step; - } - (x + (step_offset / 2.0), y) }) .filter(|(_, y)| !y.is_nan()) .collect(); - assert_eq!(i, integral_num); + let area = data2.iter().map(|(_, y)| y * step).sum(); (data2, area) } @@ -160,8 +154,7 @@ impl FunctionEntry { None } else { Some( - newtons_method_output - .iter() + dyn_iter(&newtons_method_output) .map(|x| (*x, self.function.get(*x))) .map(|(x, y)| Value::new(x, y)) .collect(), @@ -201,8 +194,7 @@ impl FunctionEntry { .collect::>() .into(); - let back_data: Vec = resolution_iter - .iter() + let back_data: Vec = dyn_iter(&resolution_iter) .cloned() .map(|x| { if let Some(i) = x_data.get_index(x) { @@ -216,8 +208,7 @@ impl FunctionEntry { self.output.back = Some(back_data); let derivative_cache = self.output.derivative.as_ref().unwrap(); - let new_derivative_data: Vec = resolution_iter - .iter() + let new_derivative_data: Vec = dyn_iter(&resolution_iter) .map(|x| { if let Some(i) = x_data.get_index(*x) { derivative_cache[i] @@ -246,9 +237,7 @@ impl FunctionEntry { if !partial_regen { self.output.back = Some({ if self.output.back.is_none() { - let data: Vec = resolution_iter - .clone() - .iter() + let data: Vec = dyn_iter(&resolution_iter) .map(|x| Value::new(*x, self.function.get(*x))) .collect(); assert_eq!(data.len(), pixel_width + 1); @@ -261,8 +250,7 @@ impl FunctionEntry { self.output.derivative = { if self.output.derivative.is_none() { - let data: Vec = resolution_iter - .iter() + let data: Vec = dyn_iter(&resolution_iter) .map(|x| Value::new(*x, self.function.get_derivative_1(*x))) .collect(); assert_eq!(data.len(), pixel_width + 1); diff --git a/src/misc.rs b/src/misc.rs index 7610c16..1f48998 100644 --- a/src/misc.rs +++ b/src/misc.rs @@ -1,6 +1,20 @@ use eframe::egui::plot::Value as EguiValue; use serde_json::Value as JsonValue; +#[cfg(not(target_arch = "wasm32"))] +use rayon::prelude::*; + +#[cfg(target_arch = "wasm32")] +pub fn dyn_iter<'a, T>(input: &'a Vec) -> impl Iterator { input.iter() } + +#[cfg(not(target_arch = "wasm32"))] +pub fn dyn_iter<'a, T>(input: &'a Vec) -> <&'a [T] as IntoParallelIterator>::Iter +where + &'a [T]: IntoParallelIterator, +{ + input.par_iter() +} + /// `SteppedVector` is used in order to efficiently sort through an ordered /// `Vec` Used in order to speedup the processing of cached data when /// moving horizontally without zoom in `FunctionEntry`. Before this struct, the