// rust/02-memory-layout.rs/*Memory layout optimization patterns and best practices*/usestd::mem;/// Demonstrates SoA (Structure of Arrays) pattern.pubstructSoAData{x:Vec<f32>,y:Vec<f32>,z:Vec<f32>,mass:Vec<f32>,}implSoAData{pubfnnew(capacity:usize)->Self{Self{x:Vec::with_capacity(capacity),y:Vec::with_capacity(capacity),z:Vec::with_capacity(capacity),mass:Vec::with_capacity(capacity),}}pubfnadd_particle(&mutself,x:f32,y:f32,z:f32,mass:f32){self.x.push(x);self.y.push(y);self.z.push(z);self.mass.push(mass);}pubfncompute_center_of_mass(&self)->(f32,f32,f32){letmuttotal_mass=0.0;letmutweighted_x=0.0;letmutweighted_y=0.0;letmutweighted_z=0.0;foriin0..self.x.len(){letmass=self.mass[i];total_mass+=mass;weighted_x+=self.x[i]*mass;weighted_y+=self.y[i]*mass;weighted_z+=self.z[i]*mass;}iftotal_mass>0.0{(weighted_x/total_mass,weighted_y/total_mass,weighted_z/total_mass,)}else{(0.0,0.0,0.0)}}}/// Demonstrates AoS (Array of Structures) pattern.pubstructAoSData{particles:Vec<Particle>,}#[derive(Clone, Copy)]pubstructParticle{pubx:f32,puby:f32,pubz:f32,pubmass:f32,}implAoSData{pubfnnew(capacity:usize)->Self{Self{particles:Vec::with_capacity(capacity),}}pubfnadd_particle(&mutself,particle:Particle){self.particles.push(particle);}pubfncompute_center_of_mass(&self)->(f32,f32,f32){letmuttotal_mass=0.0;letmutweighted_x=0.0;letmutweighted_y=0.0;letmutweighted_z=0.0;forparticlein&self.particles{total_mass+=particle.mass;weighted_x+=particle.x*particle.mass;weighted_y+=particle.y*particle.mass;weighted_z+=particle.z*particle.mass;}iftotal_mass>0.0{(weighted_x/total_mass,weighted_y/total_mass,weighted_z/total_mass,)}else{(0.0,0.0,0.0)}}}/// Demonstrates memory-efficient data structures.pubstructMemoryEfficientData{data:Vec<u8>,element_size:usize,}implMemoryEfficientData{pubfnnew(element_size:usize,capacity:usize)->Self{Self{data:vec![0;element_size*capacity],element_size,}}pubfnset_element(&mutself,index:usize,element:&[u8])->Result<(),&'staticstr>{ifelement.len()!=self.element_size{returnErr("Element size mismatch");}ifindex*self.element_size+self.element_size>self.data.len(){returnErr("Index out of bounds");}letstart=index*self.element_size;self.data[start..start+self.element_size].copy_from_slice(element);Ok(())}pubfnget_element(&self,index:usize)->Result<&[u8],&'staticstr>{ifindex*self.element_size+self.element_size>self.data.len(){returnErr("Index out of bounds");}letstart=index*self.element_size;Ok(&self.data[start..start+self.element_size])}}/// Demonstrates memory pool pattern.pubstructMemoryPool<T>{pool:Vec<T>,available:Vec<usize>,next_id:usize,}impl<T>MemoryPool<T>{pubfnnew(capacity:usize)->Self{Self{pool:Vec::with_capacity(capacity),available:Vec::new(),next_id:0,}}pubfnallocate(&mutself,item:T)->Result<usize,T>{ifletSome(index)=self.available.pop(){self.pool[index]=item;Ok(index)}elseifself.pool.len()<self.pool.capacity(){letindex=self.pool.len();self.pool.push(item);Ok(index)}else{Err(item)}}pubfndeallocate(&mutself,index:usize)->Result<T,&'staticstr>{ifindex>=self.pool.len(){returnErr("Index out of bounds");}letitem=std::mem::replace(&mutself.pool[index],unsafe{std::mem::uninitialized()});self.available.push(index);Ok(item)}pubfnget(&self,index:usize)->Option<&T>{self.pool.get(index)}pubfnget_mut(&mutself,index:usize)->Option<&mutT>{self.pool.get_mut(index)}}#[cfg(test)]modtests{usesuper::*;#[test]fntest_soa_data(){letmutsoa=SoAData::new(100);soa.add_particle(1.0,2.0,3.0,1.0);soa.add_particle(4.0,5.0,6.0,2.0);let(x,y,z)=soa.compute_center_of_mass();assert!((x-3.0).abs()<1e-6);assert!((y-4.0).abs()<1e-6);assert!((z-5.0).abs()<1e-6);}#[test]fntest_aos_data(){letmutaos=AoSData::new(100);aos.add_particle(Particle{x:1.0,y:2.0,z:3.0,mass:1.0});aos.add_particle(Particle{x:4.0,y:5.0,z:6.0,mass:2.0});let(x,y,z)=aos.compute_center_of_mass();assert!((x-3.0).abs()<1e-6);assert!((y-4.0).abs()<1e-6);assert!((z-5.0).abs()<1e-6);}#[test]fntest_memory_efficient_data(){letmutdata=MemoryEfficientData::new(4,10);letelement=[1,2,3,4];data.set_element(0,&element).unwrap();letretrieved=data.get_element(0).unwrap();assert_eq!(retrieved,&element);}#[test]fntest_memory_pool(){letmutpool=MemoryPool::new(10);letindex1=pool.allocate("Hello".to_string()).unwrap();letindex2=pool.allocate("World".to_string()).unwrap();assert_eq!(pool.get(index1),Some(&"Hello".to_string()));assert_eq!(pool.get(index2),Some(&"World".to_string()));letitem=pool.deallocate(index1).unwrap();assert_eq!(item,"Hello");}}