From 08a06d61107b980f11e75e6be216b89a2fb8573d Mon Sep 17 00:00:00 2001 From: Daniel Boros Date: Thu, 29 Aug 2024 14:38:37 +0200 Subject: [PATCH 1/6] feat: add perf improvements --- Cargo.toml | 3 + flamegraph.svg | 491 ++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 66 +------ src/noises/fgn.rs | 21 +- 4 files changed, 509 insertions(+), 72 deletions(-) create mode 100644 flamegraph.svg diff --git a/Cargo.toml b/Cargo.toml index e296c2d..a6e94c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,3 +33,6 @@ derive_builder = "0.20.0" name = "stochastic_rs" crate-type = ["cdylib", "lib"] path = "src/lib.rs" + +[profile.release] +debug = true \ No newline at end of file diff --git a/flamegraph.svg b/flamegraph.svg new file mode 100644 index 0000000..4169efa --- /dev/null +++ b/flamegraph.svg @@ -0,0 +1,491 @@ +Flame Graph Reset ZoomSearch libsystem_platform.dylib`_platform_memmove (29 samples, 4.79%)libsys..stochastic-rs`<alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter (10 samples, 1.65%)stochastic-rs`__rdl_dealloc (1 samples, 0.17%)libsystem_malloc.dylib`free_medium (5 samples, 0.83%)libsystem_kernel.dylib`madvise (5 samples, 0.83%)libsystem_platform.dylib`__bzero (21 samples, 3.47%)lib..libsystem_platform.dylib`_platform_memmove (18 samples, 2.98%)lib..stochastic-rs`<rand_distr::normal::StandardNormal as rand::distributions::distribution::Distribution<f64>>::sample (92 samples, 15.21%)stochastic-rs`<rand_dis..stochastic-rs`ndarray::impl_methods::_<impl ndarray::ArrayBase<S,D>>::map (1 samples, 0.17%)stochastic-rs`ndarray::impl_ops::arithmetic_ops::_<impl core::ops::arith::Mul<&ndarray::ArrayBase<S2,E>> for &ndarray::ArrayBase<S,D>>::mul (38 samples, 6.28%)stochast..stochastic-rs`ndarray::zip::Zip<(P1,P2,PLast),D>::collect_with_partial (38 samples, 6.28%)stochast..stochastic-rs`ndarray::iterators::to_vec_mapped (167 samples, 27.60%)stochastic-rs`ndarray::iterators::to_vec_map..stochastic-rs`<rand_distr::normal::StandardNormal as rand::distributions::distribution::Distribution<f64>>::sample (156 samples, 25.79%)stochastic-rs`<rand_distr::normal::Standa..libsystem_m.dylib`exp (2 samples, 0.33%)stochastic-rs`rustfft::array_utils::iter_chunks (13 samples, 2.15%)s..stochastic-rs`rustfft::algorithm::radix4::bitreversed_transpose (19 samples, 3.14%)sto..stochastic-rs`<stochastic_rs::noises::fgn::FgnFft as stochastic_rs::utils::Generator>::sample (519 samples, 85.79%)stochastic-rs`<stochastic_rs::noises::fgn::FgnFft as stochastic_rs::utils::Generator>::samplestochastic-rs`rustfft::Fft::process (177 samples, 29.26%)stochastic-rs`rustfft::Fft::processstochastic-rs`rustfft::neon::neon_radix4::Neon64Radix4<T>::perform_fft_out_of_place (164 samples, 27.11%)stochastic-rs`rustfft::neon::neon_radix4::N..stochastic-rs`rustfft::algorithm::radix4::reverse_bits (10 samples, 1.65%)stochastic-rs`<stochastic_rs::processes::fbm::Fbm as stochastic_rs::utils::Generator>::sample (598 samples, 98.84%)stochastic-rs`<stochastic_rs::processes::fbm::Fbm as stochastic_rs::utils::Generator>::samplestochastic-rs`ndarray::impl_methods::_<impl ndarray::ArrayBase<S,D>>::accumulate_axis_inplace (40 samples, 6.61%)stochasti..dyld`start (600 samples, 99.17%)dyld`startstochastic-rs`main (600 samples, 99.17%)stochastic-rs`mainstochastic-rs`std::rt::lang_start_internal (600 samples, 99.17%)stochastic-rs`std::rt::lang_start_internalstochastic-rs`std::rt::lang_start::_{{closure}} (600 samples, 99.17%)stochastic-rs`std::rt::lang_start::_{{closure}}stochastic-rs`std::sys::backtrace::__rust_begin_short_backtrace (600 samples, 99.17%)stochastic-rs`std::sys::backtrace::__rust_begin_short_backtracestochastic-rs`stochastic_rs::main (600 samples, 99.17%)stochastic-rs`stochastic_rs::mainstochastic-rs`stochastic_rs::processes::fbm::Fbm::new (2 samples, 0.33%)stochastic-rs`stochastic_rs::noises::fgn::FgnFft::new (2 samples, 0.33%)stochastic-rs`ndrustfft::FftHandler<T>::new (2 samples, 0.33%)stochastic-rs`rustfft::neon::neon_planner::FftPlannerNeon<T>::plan_fft (2 samples, 0.33%)stochastic-rs`rustfft::neon::neon_planner::FftPlannerNeon<T>::build_fft (2 samples, 0.33%)stochastic-rs`rustfft::neon::neon_radix4::Neon64Radix4<T>::new (2 samples, 0.33%)libsystem_kernel.dylib`__exit (1 samples, 0.17%)stochastic-rs`<rayon_core::registry::WorkerThread as core::convert::From<rayon_core::registry::ThreadBuilder>>::from (1 samples, 0.17%)libsystem_malloc.dylib`szone_malloc_should_clear (1 samples, 0.17%)libsystem_malloc.dylib`small_malloc_should_clear (1 samples, 0.17%)libsystem_malloc.dylib`mvm_allocate_pages (1 samples, 0.17%)libsystem_kernel.dylib`_kernelrpc_mach_vm_map_trap (1 samples, 0.17%)libsystem_kernel.dylib`swtch_pri (2 samples, 0.33%)all (605 samples, 100%)libsystem_pthread.dylib`thread_start (4 samples, 0.66%)libsystem_pthread.dylib`_pthread_start (4 samples, 0.66%)stochastic-rs`std::sys::pal::unix::thread::Thread::new::thread_start (4 samples, 0.66%)stochastic-rs`core::ops::function::FnOnce::call_once{{vtable.shim}} (4 samples, 0.66%)stochastic-rs`std::sys::backtrace::__rust_begin_short_backtrace (4 samples, 0.66%)stochastic-rs`rayon_core::registry::ThreadBuilder::run (4 samples, 0.66%)stochastic-rs`rayon_core::registry::WorkerThread::wait_until_cold (3 samples, 0.50%)stochastic-rs`rayon_core::join::join_context::_{{closure}} (1 samples, 0.17%) \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 7d35425..7e3fa08 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,70 +1,12 @@ use std::time::Instant; -use plotly::{common::Line, Plot, Scatter}; -use rand_distr::{Gamma, Normal, StandardNormal}; -use stochastic_rs::{ - diffusions::fou::{fou, Fou}, - jumps::{ - bates::{bates_1996, Bates1996}, - jump_fou::{jump_fou, JumpFou}, - }, - processes::fbm::Fbm, - utils::Generator, -}; +use stochastic_rs::{processes::fbm::Fbm, utils::Generator}; fn main() { let start = Instant::now(); - - let mut plot = Plot::new(); - - let jdistr = Gamma::new(1.45, 2.43).unwrap(); - let jtdistr = Gamma::new(1.45, 2.43).unwrap(); - let params = JumpFou { - hurst: 0.7, - mu: 4.0, - sigma: 1.0, - theta: 2.0, - n: 1000, - lambda: Some(0.5), - x0: Some(0.0), - t: Some(1.0), - }; - - // let bates_params = Bates1996 { - // mu: Some(0.0), - // b: Some(0.0), - // r: Some(0.0), - // r_f: Some(0.0), - // lambda: 0.5, - // k: 0.5, - // alpha: 0.5, - // beta: 0.5, - // sigma: 0.5, - // rho: 0.5, - // n: 1000, - // s0: Some(0.0), - // v0: Some(0.0), - // t: Some(1.0), - // use_sym: Some(false), - // }; - for _ in 0..1 { - let s = jump_fou(¶ms, StandardNormal); - let fbm = Fbm::new(0.95, 200, Some(200.0), None); - //let bates = bates_1996(&bates_params, StandardNormal); - //let f = fbm.sample(); - - let trace = Scatter::new((0..s.len()).collect::>(), s.to_vec()) - .mode(plotly::common::Mode::Lines) - .line( - Line::new() - .color("orange") - .shape(plotly::common::LineShape::Linear), - ) - .name("Bates"); - plot.add_trace(trace); + let fbm = Fbm::new(0.95, 10000, Some(1.0), None); + for _ in 0..1000 { + fbm.sample(); } - - plot.show(); - println!("{}", start.elapsed().as_secs_f64()); } diff --git a/src/noises/fgn.rs b/src/noises/fgn.rs index 2eaf2c8..2e48344 100644 --- a/src/noises/fgn.rs +++ b/src/noises/fgn.rs @@ -3,6 +3,8 @@ //! The `FgnFft` struct provides methods to generate fractional Gaussian noise (FGN) //! using the Fast Fourier Transform (FFT) approach. +use std::sync::{Arc, Mutex}; + use crate::utils::Generator; use ndarray::parallel::prelude::*; use ndarray::{concatenate, prelude::*}; @@ -17,10 +19,10 @@ pub struct FgnFft { n: usize, offset: usize, t: f64, - sqrt_eigenvalues: Array1>, + sqrt_eigenvalues: Arc>>, // Cache-be tárolva m: Option, - fft_handler: FftHandler, - fft_fgn: Array1>, + fft_handler: Arc>, // Cache-be tárolva + fft_fgn: Arc>>>, // Mutex védelem } impl FgnFft { @@ -79,10 +81,10 @@ impl FgnFft { n, offset, t: t.unwrap_or(1.0), - sqrt_eigenvalues, + sqrt_eigenvalues: Arc::new(sqrt_eigenvalues), // Cache-be tárolva m, - fft_handler: FftHandler::new(2 * n), - fft_fgn: Array1::>::zeros(2 * n), + fft_handler: Arc::new(FftHandler::new(2 * n)), // Cache-be tárolva + fft_fgn: Arc::new(Mutex::new(Array1::>::zeros(2 * n))), // Mutex védelem } } } @@ -105,10 +107,9 @@ impl Generator for FgnFft { 2 * self.n, ComplexDistribution::new(StandardNormal, StandardNormal), ); - let fgn = &self.sqrt_eigenvalues * &rnd; - let fft_handler = self.fft_handler.clone(); - let mut fgn_fft = self.fft_fgn.clone(); - ndfft_par(&fgn, &mut fgn_fft, &fft_handler, 0); + let fgn = &*self.sqrt_eigenvalues * &rnd; + let mut fgn_fft = self.fft_fgn.lock().unwrap().clone(); + ndfft_par(&fgn, &mut fgn_fft, &*self.fft_handler, 0); let fgn = fgn_fft .slice(s![1..self.n - self.offset + 1]) .mapv(|x: Complex| (x.re * (self.n as f64).powf(-self.hurst)) * self.t.powf(self.hurst)); From 8209c83e27a5e39ff3d7023468fe53a9ddda974a Mon Sep 17 00:00:00 2001 From: Daniel Boros Date: Sun, 1 Sep 2024 01:11:06 +0200 Subject: [PATCH 2/6] feat: speed up fbm --- Cargo.toml | 10 +++++++++- src/lib.rs | 10 ++++++++++ src/main.rs | 28 ++++++++++++++++++++++++++-- src/noises/fgn.rs | 29 +++++++++++++++-------------- src/processes/fbm.rs | 14 ++++++++++---- 5 files changed, 70 insertions(+), 21 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a6e94c9..78ac604 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,9 +25,16 @@ plotly = "0.9.0" ndarray-rand = "0.15.0" ndrustfft = "0.5.0" derive_builder = "0.20.0" +tikv-jemallocator = {version = "0.6.0", optional = true} +mimalloc = {version = "0.1.43", optional = true} [dev-dependencies] +[features] +mimalloc = ["dep:mimalloc"] +jemalloc = ["dep:tikv-jemallocator"] +default = ["jemalloc"] + [lib] name = "stochastic_rs" @@ -35,4 +42,5 @@ crate-type = ["cdylib", "lib"] path = "src/lib.rs" [profile.release] -debug = true \ No newline at end of file +debug = false +codegen-units = 1 \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 3bdfd1c..441e27f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,6 +53,16 @@ //! - Developed by [dancixx](https://github.com/dancixx). //! - Contributions and feedback are welcome! +#![feature(portable_simd)] + +#[cfg(feature = "mimalloc")] +#[global_allocator] +static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; + +#[cfg(feature = "jemalloc")] +#[global_allocator] +static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; + pub mod diffusions; pub mod interest; pub mod jumps; diff --git a/src/main.rs b/src/main.rs index 7e3fa08..27e90c6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,8 +5,32 @@ use stochastic_rs::{processes::fbm::Fbm, utils::Generator}; fn main() { let start = Instant::now(); let fbm = Fbm::new(0.95, 10000, Some(1.0), None); - for _ in 0..1000 { + (0..1000).for_each(|_| { fbm.sample(); - } + }); + println!("{}", start.elapsed().as_secs_f64()); + + let start = Instant::now(); + (0..1000).for_each(|_| { + fbm.sample(); + }); + println!("{}", start.elapsed().as_secs_f64()); + + let start = Instant::now(); + (0..1000).for_each(|_| { + fbm.sample(); + }); + println!("{}", start.elapsed().as_secs_f64()); + + let start = Instant::now(); + (0..1000).for_each(|_| { + fbm.sample(); + }); + println!("{}", start.elapsed().as_secs_f64()); + + let start = Instant::now(); + (0..1000).for_each(|_| { + fbm.sample(); + }); println!("{}", start.elapsed().as_secs_f64()); } diff --git a/src/noises/fgn.rs b/src/noises/fgn.rs index 2e48344..1c7ecc2 100644 --- a/src/noises/fgn.rs +++ b/src/noises/fgn.rs @@ -3,14 +3,14 @@ //! The `FgnFft` struct provides methods to generate fractional Gaussian noise (FGN) //! using the Fast Fourier Transform (FFT) approach. -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use crate::utils::Generator; use ndarray::parallel::prelude::*; use ndarray::{concatenate, prelude::*}; use ndarray_rand::rand_distr::StandardNormal; use ndarray_rand::RandomExt; -use ndrustfft::{ndfft_par, FftHandler}; +use ndrustfft::{ndfft, FftHandler}; use num_complex::{Complex, ComplexDistribution}; /// Struct for generating Fractional Gaussian Noise (FGN) using FFT. @@ -19,10 +19,10 @@ pub struct FgnFft { n: usize, offset: usize, t: f64, - sqrt_eigenvalues: Arc>>, // Cache-be tárolva + sqrt_eigenvalues: Arc>>, m: Option, - fft_handler: Arc>, // Cache-be tárolva - fft_fgn: Arc>>>, // Mutex védelem + fft_handler: Arc>, + fft_fgn: Arc>>>, } impl FgnFft { @@ -56,7 +56,7 @@ impl FgnFft { let offset = n_ - n; let n = n_; let mut r = Array1::linspace(0.0, n as f64, n + 1); - r.par_mapv_inplace(|x| { + r.mapv_inplace(|x| { if x == 0.0 { 1.0 } else { @@ -73,18 +73,18 @@ impl FgnFft { let data = r.mapv(|v| Complex::new(v, 0.0)); let r_fft = FftHandler::new(r.len()); let mut sqrt_eigenvalues = Array1::>::zeros(r.len()); - ndfft_par(&data, &mut sqrt_eigenvalues, &r_fft, 0); - sqrt_eigenvalues.par_mapv_inplace(|x| Complex::new((x.re / (2.0 * n as f64)).sqrt(), x.im)); + ndfft(&data, &mut sqrt_eigenvalues, &r_fft, 0); + sqrt_eigenvalues.mapv_inplace(|x| Complex::new((x.re / (2.0 * n as f64)).sqrt(), x.im)); Self { hurst, n, offset, t: t.unwrap_or(1.0), - sqrt_eigenvalues: Arc::new(sqrt_eigenvalues), // Cache-be tárolva + sqrt_eigenvalues: Arc::new(sqrt_eigenvalues), m, - fft_handler: Arc::new(FftHandler::new(2 * n)), // Cache-be tárolva - fft_fgn: Arc::new(Mutex::new(Array1::>::zeros(2 * n))), // Mutex védelem + fft_handler: Arc::new(FftHandler::new(2 * n)), + fft_fgn: Arc::new(RwLock::new(Array1::>::zeros(2 * n))), } } } @@ -108,11 +108,12 @@ impl Generator for FgnFft { ComplexDistribution::new(StandardNormal, StandardNormal), ); let fgn = &*self.sqrt_eigenvalues * &rnd; - let mut fgn_fft = self.fft_fgn.lock().unwrap().clone(); - ndfft_par(&fgn, &mut fgn_fft, &*self.fft_handler, 0); + let mut fgn_fft = self.fft_fgn.read().unwrap().clone(); + ndfft(&fgn, &mut fgn_fft, &*self.fft_handler, 0); + let scale = (self.n as f64).powf(-self.hurst) * self.t.powf(self.hurst); let fgn = fgn_fft .slice(s![1..self.n - self.offset + 1]) - .mapv(|x: Complex| (x.re * (self.n as f64).powf(-self.hurst)) * self.t.powf(self.hurst)); + .mapv(|x: Complex| x.re * scale); fgn } diff --git a/src/processes/fbm.rs b/src/processes/fbm.rs index b470d24..d9f97a8 100644 --- a/src/processes/fbm.rs +++ b/src/processes/fbm.rs @@ -1,7 +1,7 @@ //! Fractional Brownian Motion (fBM) generator. use crate::{noises::fgn::FgnFft, utils::Generator}; -use ndarray::{Array1, Array2, Axis}; +use ndarray::{s, Array1, Array2, Axis}; use rayon::prelude::*; /// Struct for generating Fractional Brownian Motion (fBM). @@ -67,9 +67,15 @@ impl Generator for Fbm { /// ``` fn sample(&self) -> Array1 { let fgn = self.fgn.as_ref().unwrap().sample(); - let mut fbm = Array1::::from(fgn); - fbm.accumulate_axis_inplace(Axis(0), |&x, y| *y += x); - vec![0.0].into_iter().chain(fbm).collect() + + let mut fbm = Array1::::zeros(self.n); + fbm.slice_mut(s![1..]).assign(&fgn); + + for i in 1..self.n { + fbm[i] += fbm[i - 1]; + } + + fbm } /// Generates parallel samples of fractional Brownian motion (fBM). From cf0fb3196b4ed684f69fa0b3f09cbbd2f6683156 Mon Sep 17 00:00:00 2001 From: Daniel Boros Date: Sun, 1 Sep 2024 01:14:39 +0200 Subject: [PATCH 3/6] feat: add fbm plot test --- src/main.rs | 37 +------------------------------------ src/processes/fbm.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 36 deletions(-) diff --git a/src/main.rs b/src/main.rs index 27e90c6..f328e4d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,36 +1 @@ -use std::time::Instant; - -use stochastic_rs::{processes::fbm::Fbm, utils::Generator}; - -fn main() { - let start = Instant::now(); - let fbm = Fbm::new(0.95, 10000, Some(1.0), None); - (0..1000).for_each(|_| { - fbm.sample(); - }); - println!("{}", start.elapsed().as_secs_f64()); - - let start = Instant::now(); - (0..1000).for_each(|_| { - fbm.sample(); - }); - println!("{}", start.elapsed().as_secs_f64()); - - let start = Instant::now(); - (0..1000).for_each(|_| { - fbm.sample(); - }); - println!("{}", start.elapsed().as_secs_f64()); - - let start = Instant::now(); - (0..1000).for_each(|_| { - fbm.sample(); - }); - println!("{}", start.elapsed().as_secs_f64()); - - let start = Instant::now(); - (0..1000).for_each(|_| { - fbm.sample(); - }); - println!("{}", start.elapsed().as_secs_f64()); -} +fn main() {} diff --git a/src/processes/fbm.rs b/src/processes/fbm.rs index d9f97a8..690a23c 100644 --- a/src/processes/fbm.rs +++ b/src/processes/fbm.rs @@ -108,3 +108,29 @@ impl Generator for Fbm { xs } } + +#[cfg(test)] +mod tests { + use plotly::{common::Line, Plot, Scatter}; + + use super::*; + + #[test] + fn plot() { + let fbm = Fbm::new(0.45, 1000, Some(1.0), Some(10)); + let mut plot = Plot::new(); + let d = fbm.sample_par(); + for data in d.axis_iter(Axis(0)) { + let trace = Scatter::new((0..data.len()).collect::>(), data.to_vec()) + .mode(plotly::common::Mode::Lines) + .line( + Line::new() + .color("orange") + .shape(plotly::common::LineShape::Linear), + ) + .name("Fbm"); + plot.add_trace(trace); + } + plot.show(); + } +} From 578ca84e484fe73e2aa937c01e117ce8f8c516ad Mon Sep 17 00:00:00 2001 From: Daniel Boros Date: Sun, 1 Sep 2024 01:22:31 +0200 Subject: [PATCH 4/6] feat: add fgn plot tes --- src/noises/fgn.rs | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/noises/fgn.rs b/src/noises/fgn.rs index 1c7ecc2..3efa876 100644 --- a/src/noises/fgn.rs +++ b/src/noises/fgn.rs @@ -138,12 +138,38 @@ impl Generator for FgnFft { panic!("m must be specified for parallel sampling"); } - let mut xs = Array2::zeros((self.m.unwrap(), self.n)); + let mut xs = Array2::zeros((self.m.unwrap(), self.n - self.offset)); xs.axis_iter_mut(Axis(0)).into_par_iter().for_each(|mut x| { - x.assign(&self.sample()); + x.assign(&self.sample().slice(s![..self.n - self.offset])); }); xs } } + +#[cfg(test)] +mod tests { + use plotly::{common::Line, Plot, Scatter}; + + use super::*; + + #[test] + fn plot() { + let fgn = FgnFft::new(0.9, 1000, Some(1.0), Some(1)); + let mut plot = Plot::new(); + let d = fgn.sample_par(); + for data in d.axis_iter(Axis(0)) { + let trace = Scatter::new((0..data.len()).collect::>(), data.to_vec()) + .mode(plotly::common::Mode::Lines) + .line( + Line::new() + .color("orange") + .shape(plotly::common::LineShape::Linear), + ) + .name("Fgn"); + plot.add_trace(trace); + } + plot.show(); + } +} From 2733992a87a39104dba555ef7a5c98edf2743ba7 Mon Sep 17 00:00:00 2001 From: Daniel Boros Date: Sun, 1 Sep 2024 13:10:43 +0200 Subject: [PATCH 5/6] feat: update deps --- .gitignore | 1 + Cargo.toml | 13 +- flamegraph.svg | 491 ------------------------------------------------- 3 files changed, 7 insertions(+), 498 deletions(-) delete mode 100644 flamegraph.svg diff --git a/.gitignore b/.gitignore index 4fffb2f..fd3233f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target /Cargo.lock +flamegraph.svg \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 78ac604..065090a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "stochastic-rs" -version = "0.6.5" +version = "0.7.0" edition = "2021" license = "MIT" description = "A Rust library for stochastic processes" @@ -20,20 +20,19 @@ num-complex = { version = "0.4.6", features = ["rand"] } rand = "0.8.5" rand_distr = "0.4.3" rayon = "1.10.0" -indicatif = "0.17.7" plotly = "0.9.0" ndarray-rand = "0.15.0" ndrustfft = "0.5.0" -derive_builder = "0.20.0" -tikv-jemallocator = {version = "0.6.0", optional = true} -mimalloc = {version = "0.1.43", optional = true} +derive_builder = "0.20.1" +tikv-jemallocator = { version = "0.6.0", optional = true } +mimalloc = { version = "0.1.43", optional = true } [dev-dependencies] [features] mimalloc = ["dep:mimalloc"] jemalloc = ["dep:tikv-jemallocator"] -default = ["jemalloc"] +default = [] [lib] @@ -43,4 +42,4 @@ path = "src/lib.rs" [profile.release] debug = false -codegen-units = 1 \ No newline at end of file +codegen-units = 1 diff --git a/flamegraph.svg b/flamegraph.svg deleted file mode 100644 index 4169efa..0000000 --- a/flamegraph.svg +++ /dev/null @@ -1,491 +0,0 @@ -Flame Graph Reset ZoomSearch libsystem_platform.dylib`_platform_memmove (29 samples, 4.79%)libsys..stochastic-rs`<alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter (10 samples, 1.65%)stochastic-rs`__rdl_dealloc (1 samples, 0.17%)libsystem_malloc.dylib`free_medium (5 samples, 0.83%)libsystem_kernel.dylib`madvise (5 samples, 0.83%)libsystem_platform.dylib`__bzero (21 samples, 3.47%)lib..libsystem_platform.dylib`_platform_memmove (18 samples, 2.98%)lib..stochastic-rs`<rand_distr::normal::StandardNormal as rand::distributions::distribution::Distribution<f64>>::sample (92 samples, 15.21%)stochastic-rs`<rand_dis..stochastic-rs`ndarray::impl_methods::_<impl ndarray::ArrayBase<S,D>>::map (1 samples, 0.17%)stochastic-rs`ndarray::impl_ops::arithmetic_ops::_<impl core::ops::arith::Mul<&ndarray::ArrayBase<S2,E>> for &ndarray::ArrayBase<S,D>>::mul (38 samples, 6.28%)stochast..stochastic-rs`ndarray::zip::Zip<(P1,P2,PLast),D>::collect_with_partial (38 samples, 6.28%)stochast..stochastic-rs`ndarray::iterators::to_vec_mapped (167 samples, 27.60%)stochastic-rs`ndarray::iterators::to_vec_map..stochastic-rs`<rand_distr::normal::StandardNormal as rand::distributions::distribution::Distribution<f64>>::sample (156 samples, 25.79%)stochastic-rs`<rand_distr::normal::Standa..libsystem_m.dylib`exp (2 samples, 0.33%)stochastic-rs`rustfft::array_utils::iter_chunks (13 samples, 2.15%)s..stochastic-rs`rustfft::algorithm::radix4::bitreversed_transpose (19 samples, 3.14%)sto..stochastic-rs`<stochastic_rs::noises::fgn::FgnFft as stochastic_rs::utils::Generator>::sample (519 samples, 85.79%)stochastic-rs`<stochastic_rs::noises::fgn::FgnFft as stochastic_rs::utils::Generator>::samplestochastic-rs`rustfft::Fft::process (177 samples, 29.26%)stochastic-rs`rustfft::Fft::processstochastic-rs`rustfft::neon::neon_radix4::Neon64Radix4<T>::perform_fft_out_of_place (164 samples, 27.11%)stochastic-rs`rustfft::neon::neon_radix4::N..stochastic-rs`rustfft::algorithm::radix4::reverse_bits (10 samples, 1.65%)stochastic-rs`<stochastic_rs::processes::fbm::Fbm as stochastic_rs::utils::Generator>::sample (598 samples, 98.84%)stochastic-rs`<stochastic_rs::processes::fbm::Fbm as stochastic_rs::utils::Generator>::samplestochastic-rs`ndarray::impl_methods::_<impl ndarray::ArrayBase<S,D>>::accumulate_axis_inplace (40 samples, 6.61%)stochasti..dyld`start (600 samples, 99.17%)dyld`startstochastic-rs`main (600 samples, 99.17%)stochastic-rs`mainstochastic-rs`std::rt::lang_start_internal (600 samples, 99.17%)stochastic-rs`std::rt::lang_start_internalstochastic-rs`std::rt::lang_start::_{{closure}} (600 samples, 99.17%)stochastic-rs`std::rt::lang_start::_{{closure}}stochastic-rs`std::sys::backtrace::__rust_begin_short_backtrace (600 samples, 99.17%)stochastic-rs`std::sys::backtrace::__rust_begin_short_backtracestochastic-rs`stochastic_rs::main (600 samples, 99.17%)stochastic-rs`stochastic_rs::mainstochastic-rs`stochastic_rs::processes::fbm::Fbm::new (2 samples, 0.33%)stochastic-rs`stochastic_rs::noises::fgn::FgnFft::new (2 samples, 0.33%)stochastic-rs`ndrustfft::FftHandler<T>::new (2 samples, 0.33%)stochastic-rs`rustfft::neon::neon_planner::FftPlannerNeon<T>::plan_fft (2 samples, 0.33%)stochastic-rs`rustfft::neon::neon_planner::FftPlannerNeon<T>::build_fft (2 samples, 0.33%)stochastic-rs`rustfft::neon::neon_radix4::Neon64Radix4<T>::new (2 samples, 0.33%)libsystem_kernel.dylib`__exit (1 samples, 0.17%)stochastic-rs`<rayon_core::registry::WorkerThread as core::convert::From<rayon_core::registry::ThreadBuilder>>::from (1 samples, 0.17%)libsystem_malloc.dylib`szone_malloc_should_clear (1 samples, 0.17%)libsystem_malloc.dylib`small_malloc_should_clear (1 samples, 0.17%)libsystem_malloc.dylib`mvm_allocate_pages (1 samples, 0.17%)libsystem_kernel.dylib`_kernelrpc_mach_vm_map_trap (1 samples, 0.17%)libsystem_kernel.dylib`swtch_pri (2 samples, 0.33%)all (605 samples, 100%)libsystem_pthread.dylib`thread_start (4 samples, 0.66%)libsystem_pthread.dylib`_pthread_start (4 samples, 0.66%)stochastic-rs`std::sys::pal::unix::thread::Thread::new::thread_start (4 samples, 0.66%)stochastic-rs`core::ops::function::FnOnce::call_once{{vtable.shim}} (4 samples, 0.66%)stochastic-rs`std::sys::backtrace::__rust_begin_short_backtrace (4 samples, 0.66%)stochastic-rs`rayon_core::registry::ThreadBuilder::run (4 samples, 0.66%)stochastic-rs`rayon_core::registry::WorkerThread::wait_until_cold (3 samples, 0.50%)stochastic-rs`rayon_core::join::join_context::_{{closure}} (1 samples, 0.17%) \ No newline at end of file From ac41b0366008451c01c0b2991b5038c80e228643 Mon Sep 17 00:00:00 2001 From: Daniel Boros Date: Sun, 1 Sep 2024 13:37:38 +0200 Subject: [PATCH 6/6] chore: stop doctest --- Cargo.toml | 3 ++- src/main.rs | 25 ++++++++++++++++++++++++- src/noises/fgn.rs | 6 ++---- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 065090a..9d02490 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,13 +32,14 @@ mimalloc = { version = "0.1.43", optional = true } [features] mimalloc = ["dep:mimalloc"] jemalloc = ["dep:tikv-jemallocator"] -default = [] +default = ["jemalloc"] [lib] name = "stochastic_rs" crate-type = ["cdylib", "lib"] path = "src/lib.rs" +doctest = false [profile.release] debug = false diff --git a/src/main.rs b/src/main.rs index f328e4d..16dbb49 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1 +1,24 @@ -fn main() {} +use stochastic_rs::{processes::fbm::Fbm, utils::Generator}; + +fn main() { + let fbm = Fbm::new(0.75, 10000, Some(1.0), None); + let mut runs = Vec::new(); + + for _ in 0..20 { + let start = std::time::Instant::now(); + for _ in 0..1000 { + let _ = fbm.sample(); + } + + let duration = start.elapsed(); + println!( + "Time elapsed in expensive_function() is: {:?}", + duration.as_secs_f32() + ); + runs.push(duration.as_secs_f32()); + } + + let sum: f32 = runs.iter().sum(); + let average = sum / runs.len() as f32; + println!("Average time: {}", average); +} diff --git a/src/noises/fgn.rs b/src/noises/fgn.rs index 3efa876..306cbd3 100644 --- a/src/noises/fgn.rs +++ b/src/noises/fgn.rs @@ -3,7 +3,7 @@ //! The `FgnFft` struct provides methods to generate fractional Gaussian noise (FGN) //! using the Fast Fourier Transform (FFT) approach. -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use crate::utils::Generator; use ndarray::parallel::prelude::*; @@ -22,7 +22,6 @@ pub struct FgnFft { sqrt_eigenvalues: Arc>>, m: Option, fft_handler: Arc>, - fft_fgn: Arc>>>, } impl FgnFft { @@ -84,7 +83,6 @@ impl FgnFft { sqrt_eigenvalues: Arc::new(sqrt_eigenvalues), m, fft_handler: Arc::new(FftHandler::new(2 * n)), - fft_fgn: Arc::new(RwLock::new(Array1::>::zeros(2 * n))), } } } @@ -108,7 +106,7 @@ impl Generator for FgnFft { ComplexDistribution::new(StandardNormal, StandardNormal), ); let fgn = &*self.sqrt_eigenvalues * &rnd; - let mut fgn_fft = self.fft_fgn.read().unwrap().clone(); + let mut fgn_fft = Array1::>::zeros(2 * self.n); ndfft(&fgn, &mut fgn_fft, &*self.fft_handler, 0); let scale = (self.n as f64).powf(-self.hurst) * self.t.powf(self.hurst); let fgn = fgn_fft