From 82ef9c24a67b3ce4809aac1c2f73bc585e754f89 Mon Sep 17 00:00:00 2001 From: Simon Gardling Date: Fri, 13 May 2022 09:47:08 -0400 Subject: [PATCH] more efficient partial regen loop --- Cargo.lock | 12 +++++++ Cargo.toml | 1 + src/function_entry.rs | 73 ++++++++++++++++++++++++------------------- 3 files changed, 53 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 51e626c..dc740ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2340,6 +2340,17 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" +[[package]] +name = "unzip-n" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e7e85a0596447f0f2ac090e16bc4c516c6fe91771fb0c0ccf7fa3dae896b9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "url" version = "2.2.2" @@ -2787,6 +2798,7 @@ dependencies = [ "tracing", "tracing-subscriber", "tracing-wasm", + "unzip-n", "uuid 1.0.0", "wasm-bindgen", "web-sys", diff --git a/Cargo.toml b/Cargo.toml index 018325b..9432de7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,6 +57,7 @@ uuid = { version = "1", features = ["v4", "fast-rng", "js"] } bincode = "1.3" serde = "1" byte-unit = { version = "4", default-features = false } +unzip-n = "0.1" [dev-dependencies] benchmarks = { path = "./benchmarks" } diff --git a/src/function_entry.rs b/src/function_entry.rs index 0ae6ed8..f3ca8fc 100644 --- a/src/function_entry.rs +++ b/src/function_entry.rs @@ -15,6 +15,7 @@ use std::{ fmt::{self, Debug}, intrinsics::assume, }; +use unzip_n::unzip_n; #[cfg(threading)] use rayon::iter::ParallelIterator; @@ -307,25 +308,38 @@ impl FunctionEntry { let x_data_1: Vec = self.back_data.iter().map(|ele| ele.x).collect::>(); let x_data: SteppedVector = x_data_1.as_slice().into(); - let (back_data, derivative_data_1): (Vec, Vec>) = - dyn_iter(&resolution_iter) - .map(|x| { - if let Some(i) = x_data.get_index(x) { - ( - self.back_data[i], - derivative_required.then(|| self.derivative_data[i]), - ) - } else { - ( - Value::new(*x, self.function.get(*x)), - derivative_required - .then(|| Value::new(*x, self.function.get_derivative_1(*x))), - ) - } - }) - .collect::)>>() - .into_iter() - .unzip(); + let do_nth_derivative = self.nth_derviative && self.nth_derivative_data.is_some(); + + let nth_derivative_data = self.nth_derivative_data.as_ref(); + unzip_n!(3); + let (back_data, derivative_data_1, new_nth_derivative_data): ( + Vec, + Vec>, + Vec>, + ) = dyn_iter(&resolution_iter) + .map(|x| { + if let Some(i) = x_data.get_index(x) { + return ( + self.back_data[i], + derivative_required.then(|| self.derivative_data[i]), + do_nth_derivative.then(|| unsafe { + nth_derivative_data.map(|data| data[i]).unwrap_unchecked() + }), + ); + } else { + return ( + Value::new(*x, self.function.get(*x)), + derivative_required + .then(|| Value::new(*x, self.function.get_derivative_1(*x))), + do_nth_derivative.then(|| { + Value::new(*x, self.function.get_nth_derivative(self.curr_nth, *x)) + }), + ); + } + }) + .collect::, Option)>>() + .into_iter() + .unzip_n_vec(); debug_assert_eq!(back_data.len(), settings.plot_width + 1); debug_assert_eq!(derivative_data_1.len(), settings.plot_width + 1); @@ -342,20 +356,13 @@ impl FunctionEntry { self.invalidate_derivative(); } - if self.nth_derviative && let Some(nth_derivative_data) = &self.nth_derivative_data { - let new_nth_derivative_data: Vec = dyn_iter(&resolution_iter) - .map(|x| { - if let Some(i) = x_data.get_index(x) { - (*nth_derivative_data)[i] - } else { - Value::new(*x, self.function.get_nth_derivative(self.curr_nth, *x)) - } - }) - .collect(); - - debug_assert_eq!(new_nth_derivative_data.len(), settings.plot_width + 1); - - self.nth_derivative_data = Some(new_nth_derivative_data); + if do_nth_derivative { + self.nth_derivative_data = Some( + new_nth_derivative_data + .into_iter() + .map(|c| unsafe { c.unwrap_unchecked() }) + .collect(), + ); } else { self.invalidate_nth(); }