use scirs2_core::memory_efficient::{create_mmap, create_temp_mmap, AccessMode};
use scirs2_core::ndarray_ext::{Array1, Array2, Array3, Ix2, Ix3};
use std::path::Path;
use std::time::Instant;
use tempfile::tempdir;
#[allow(dead_code)]
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Memory-Mapped Arrays Example");
println!("============================\n");
let temp_dir = tempdir()?;
println!("Using temporary directory: {:?}", temp_dir.path());
basic_example(temp_dir.path())?;
large_array_example(temp_dir.path())?;
multi_dimensional_example(temp_dir.path())?;
performance_comparison_example(temp_dir.path())?;
Ok(())
}
#[allow(dead_code)]
fn basic_example(tempdir: &Path) -> Result<(), Box<dyn std::error::Error>> {
println!("\n1. Basic Memory-Mapped Array Example");
println!("----------------------------------");
let data = Array1::<f64>::linspace(0., 99., 100);
println!("Created a 1D array with 100 elements");
let file_path = tempdir.join("basic_example.bin");
let mmap = create_mmap(&data, &file_path, AccessMode::Write, 0)?;
println!("Created memory-mapped array at: {:?}", file_path);
println!(" Shape: {:?}", mmap.shape);
println!(" Size: {} elements", mmap.size);
println!(" Mode: {:?}", mmap.mode);
let loaded_data = mmap.as_array::<scirs2_core::ndarray::Ix1>()?;
println!(
"Verifying data: [0] = {}, [50] = {}, [99] = {}",
loaded_data[0], loaded_data[50], loaded_data[99]
);
Ok(())
}
#[allow(dead_code)]
fn large_array_example(tempdir: &Path) -> Result<(), Box<dyn std::error::Error>> {
println!("\n2. Large Array Processing Example");
println!("-------------------------------");
let rows = 1000;
let cols = 1000;
let data = Array2::<f32>::from_shape_fn((rows, cols), |(i, j)| (i * cols + j) as f32);
let size_mb = (rows * cols * std::mem::size_of::<f32>()) as f64 / (1024.0 * 1024.0);
println!("Created a {}x{} array ({:.2} MB)", rows, cols, size_mb);
let mut mmap = create_temp_mmap(&data, AccessMode::ReadWrite, 0)?;
println!("Created temporary memory-mapped array");
let sum = mmap.as_array::<Ix2>()?.sum();
println!("Sum of all elements: {}", sum);
let max = mmap
.as_array::<Ix2>()?
.fold(f32::MIN, |a, &b| f32::max(a, b));
println!("Maximum element: {}", max);
{
let mut array_mut = mmap.as_array_mut::<Ix2>()?;
for i in 0..std::cmp::min(rows, cols) {
array_mut[[i, i]] = 0.0;
}
}
mmap.flush()?;
println!("Modified diagonal elements through memory mapping");
Ok(())
}
#[allow(dead_code)]
fn multi_dimensional_example(tempdir: &Path) -> Result<(), Box<dyn std::error::Error>> {
println!("\n3. Multi-Dimensional Array Example");
println!("---------------------------------");
let shape = (10, 10, 10);
let data = Array3::<i32>::from_shape_fn(shape, |(i, j, k)| (i * 100 + j * 10 + k) as i32);
println!("Created a 10x10x10 3D array");
let mmap = create_temp_mmap(&data, AccessMode::ReadWrite, 0)?;
println!("Created temporary memory-mapped 3D array");
let array = mmap.as_array::<Ix3>()?;
println!("Accessing some elements directly:");
println!("Value at [5, 0, 0]: {}", array[[5, 0, 0]]);
println!("Value at [5, 0, 1]: {}", array[[5, 0, 1]]);
println!("Value at [5, 0, 2]: {}", array[[5, 0, 2]]);
println!("Value at [5, 1, 0]: {}", array[[5, 1, 0]]);
println!("3D array shape: {:?}", array.shape());
Ok(())
}
#[allow(dead_code)]
fn performance_comparison_example(tempdir: &Path) -> Result<(), Box<dyn std::error::Error>> {
println!("\n4. Performance Comparison Example");
println!("--------------------------------");
let rows = 1000;
let cols = 1000;
let size_mb = (rows * cols * std::mem::size_of::<f64>()) as f64 / (1024.0 * 1024.0);
println!(
"Using a {}x{} array ({:.2} MB) for performance comparison",
rows, cols, size_mb
);
let start = Instant::now();
let data =
Array2::<f64>::from_shape_fn((rows, cols), |(i, j)| i as f64 * cols as f64 + j as f64);
let in_memory_creation_time = start.elapsed();
println!(
"In-memory array creation time: {:?}",
in_memory_creation_time
);
let start = Instant::now();
let mmap = create_temp_mmap(&data, AccessMode::ReadWrite, 0)?;
let mmap_creation_time = start.elapsed();
println!(
"Memory-mapped array creation time: {:?}",
mmap_creation_time
);
let start = Instant::now();
let in_memory_sum = data.sum();
let in_memory_read_time = start.elapsed();
println!(
"In-memory array sum calculation time: {:?}",
in_memory_read_time
);
let start = Instant::now();
let mmap_sum = mmap.as_array::<Ix2>()?.sum();
let mmap_read_time = start.elapsed();
println!(
"Memory-mapped array sum calculation time: {:?}",
mmap_read_time
);
assert!((in_memory_sum - mmap_sum).abs() < 1e-10);
println!("Both methods produced the same sum: {}", in_memory_sum);
println!("\nPerformance Summary:");
println!(
" Creation: Memory-mapped took {:.2}x the time of in-memory",
mmap_creation_time.as_secs_f64() / in_memory_creation_time.as_secs_f64()
);
println!(
" Reading: Memory-mapped took {:.2}x the time of in-memory",
mmap_read_time.as_secs_f64() / in_memory_read_time.as_secs_f64()
);
println!(" Note: The real advantage is for arrays larger than RAM");
Ok(())
}