# HG changeset patch # User alfadur # Date 1679792029 -10800 # Node ID 8035f7452b48f987f10e3e8fadccd0ae932a1e06 # Parent ea370bfda70520582a48851835d6b33ba173af7c optimize type mask iteration diff -r ea370bfda705 -r 8035f7452b48 rust/hwphysics/src/data.rs --- a/rust/hwphysics/src/data.rs Sun Mar 26 02:31:04 2023 +0300 +++ b/rust/hwphysics/src/data.rs Sun Mar 26 03:53:49 2023 +0300 @@ -140,14 +140,17 @@ .add(size_of::() * max_elements as usize) }; - for i in 0..element_sizes.len() { - if mask & (1 << i as u64) != 0 { - unsafe { - address = address.add(address.align_offset(element_alignments[i] as usize)); - blocks[i] = Some(NonNull::new_unchecked(address)); - address = address.add(element_sizes[i] as usize * max_elements as usize) - }; - } + let mut mask_bits = mask; + while mask_bits != 0 { + let i = mask_bits.trailing_zeros() as usize; + + unsafe { + address = address.add(address.align_offset(element_alignments[i] as usize)); + blocks[i] = Some(NonNull::new_unchecked(address)); + address = address.add(element_sizes[i] as usize * max_elements as usize) + }; + + mask_bits &= mask_bits - 1; } Self { @@ -159,6 +162,7 @@ } } + #[inline] fn gear_ids(&self) -> &[GearId] { unsafe { slice::from_raw_parts( @@ -168,6 +172,7 @@ } } + #[inline] fn gear_ids_mut(&mut self) -> &mut [GearId] { unsafe { slice::from_raw_parts_mut( @@ -177,6 +182,7 @@ } } + #[inline] fn is_full(&self) -> bool { self.elements_count == self.max_elements } @@ -275,26 +281,30 @@ debug_assert!(!dest_block.is_full()); let dest_index = dest_block.elements_count; - for i in 0..self.types.len() { - if src_mask.type_mask & (1 << i as u64) != 0 { - let size = self.element_sizes[i]; - let src_ptr = src_block.component_blocks[i].unwrap().as_ptr(); - let dest_ptr = dest_block.component_blocks[i].unwrap().as_ptr(); - unsafe { + + let mut type_mask = src_mask.type_mask; + while type_mask != 0 { + let i = type_mask.trailing_zeros() as usize; + + let size = self.element_sizes[i]; + let src_ptr = src_block.component_blocks[i].unwrap().as_ptr(); + let dest_ptr = dest_block.component_blocks[i].unwrap().as_ptr(); + unsafe { + copy_nonoverlapping( + src_ptr.add((src_index * size) as usize), + dest_ptr.add((dest_index * size) as usize), + size as usize, + ); + if src_index < src_block.elements_count - 1 { copy_nonoverlapping( - src_ptr.add((src_index * size) as usize), - dest_ptr.add((dest_index * size) as usize), + src_ptr.add((size * (src_block.elements_count - 1)) as usize), + src_ptr.add((size * src_index) as usize), size as usize, ); - if src_index < src_block.elements_count - 1 { - copy_nonoverlapping( - src_ptr.add((size * (src_block.elements_count - 1)) as usize), - src_ptr.add((size * src_index) as usize), - size as usize, - ); - } } } + + type_mask &= type_mask - 1; } let src_block = &mut self.blocks[src_block_index as usize];