From 8b685b21282847358c28a0d51b0be7a89b48681c Mon Sep 17 00:00:00 2001 From: teridax Date: Sun, 30 Apr 2023 17:34:23 +0200 Subject: [PATCH] fixed memory benchmarking --- sparse_vector/src/main.rs | 54 ++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/sparse_vector/src/main.rs b/sparse_vector/src/main.rs index 0e214ff..948087c 100644 --- a/sparse_vector/src/main.rs +++ b/sparse_vector/src/main.rs @@ -32,15 +32,9 @@ impl SparseVec { pub fn new(elements: usize, non_null: f64) -> Self { let non_zero_elements = (elements as f64 * non_null) as usize; - let heap_element_size = std::mem::size_of::() + std::mem::size_of::(); - - println!("Estimated size on heap: {}", ByteSize::b((non_zero_elements * heap_element_size) as u64)); - - println!("allocating..."); let mut values = Vec::with_capacity(non_zero_elements); let mut indices = Vec::with_capacity(non_zero_elements); - println!("generating some data..."); let mut rng = rand::thread_rng(); for i in 0..non_zero_elements { @@ -57,8 +51,8 @@ impl SparseVec { } } +#[inline] fn binary_search(target: usize, indices: &[usize], values: &[f64]) -> f64 { - let mut range = 0..indices.len(); loop { let mut median = (range.end - range.start) >> 1; @@ -69,7 +63,9 @@ fn binary_search(target: usize, indices: &[usize], values: &[f64]) -> f64 { if indices[median] == target { return values[median]; - } else if indices[median] > target { + } + + if indices[median] > target { range.end = median; } else { range.start = median; @@ -79,20 +75,42 @@ fn binary_search(target: usize, indices: &[usize], values: &[f64]) -> f64 { 0.0 } -fn main() { - let now = Instant::now(); - // generate a sparse vector with 10^10 random elements - // but only with 2% of them being non-null - let vec = SparseVec::new(10_usize.pow(10), 0.02); - println!("Created sparse vector took: {}s", Instant::now().sub(now).as_secs_f32()); +macro_rules! time { + ($name:literal, $block:expr) => {{ + let start = Instant::now(); + $block; + println!("{} took {}s", $name, start.elapsed().as_secs_f64()); + }} +} - println!("Sparse vector stack bytes: {} B", std::mem::size_of_val(&vec)); +fn main() { + + /// Theoretical size of the vector in elements + /// This would mean the we would require 10 GBs of memory to store a single vector + const VECTOR_SIZE: usize = 10_000_000_000; + /// Ratio between null and non null elements per vector + /// this means that only `NULL_NON_NULL_RATIO * 100%` elements of every vector will + /// be non-null and thus actually stored + const NULL_NON_NULL_RATIO: f64 = 0.02; + + let non_zero_elements = (VECTOR_SIZE as f64 * NULL_NON_NULL_RATIO) as usize; + let heap_element_size = std::mem::size_of::() + std::mem::size_of::(); + + println!("Estimated size on heap: {}", ByteSize::b((non_zero_elements * heap_element_size) as u64)); + println!("Size on stack: {} B", std::mem::size_of::()); + + let mut vec: SparseVec; + + time!("Sparse vector creation", { + // generate a vector + vec = SparseVec::new(VECTOR_SIZE, NULL_NON_NULL_RATIO); + }); // many statistics are cached and only updated when the epoch is advanced. epoch::advance().unwrap(); println!("Heap allocated bytes (total): {}", ByteSize::b(stats::allocated::read().unwrap() as u64)); - let now = Instant::now(); - vec.dot(&vec); - println!("Dot product took: {}s", Instant::now().sub(now).as_secs_f32()); + time!("Sparse vector dot product", { + vec.dot(&vec); + }); } \ No newline at end of file