5个版本 (重大更改)
0.5.0 | 2019年8月14日 |
---|---|
0.4.0 | 2019年7月14日 |
0.3.0 | 2019年6月22日 |
0.2.0 | 2019年6月21日 |
0.1.0 | 2019年6月16日 |
#2227 in 数据结构
每月21次 下载
28KB
531 代码行
Soa2、Soa3、..SoaN 是具有类似元组Vec API的泛型集合,但每个字段存储为独立的切片。这种布局的优势在于在迭代数据时,只需从RAM中加载子集。
这种方法在游戏引擎中很常见,特别是在实体组件系统中,但适用于任何缓存一致性和内存带宽对性能很重要的地方。
示例
# use soa_vec::Soa3;
/// Some 'entity' data.
# #[derive(Copy, Clone)]
struct Position { x: f64, y: f64 }
# #[derive(Copy, Clone)]
struct Velocity { dx: f64, dy: f64 }
struct ColdData { /* Potentially many fields omitted here */ }
# use std::ops::Add;
# impl Add<Velocity> for Position { type Output=Self; fn add(self, other: Velocity) -> Self { Self { x: self.x + other.dx, y: self.y + other.dy } } }
// Create a vec of entities
let mut entities = Soa3::new();
entities.push((Position {x: 1.0, y: 2.0}, Velocity { dx: 0.0, dy: 0.5 }, ColdData {}));
entities.push((Position {x: 0.0, y: 2.0}, Velocity { dx: 0.5, dy: 0.5 }, ColdData {}));
// Update entities. This loop only loads position and velocity data, while skipping over
// the ColdData which is not necessary for the physics simulation.
let (positions, velocities, _cold) = entities.iters_mut();
for (position, velocity) in positions.zip(velocities) {
*position = *position + *velocity;
}
// Remove an entity
entities.swap_remove(0);
// Sort entities by position on y axis
// The fields are passed by reference, so velocity and cold data are not loaded
// until such time as the items are being swapped which runs in O(N)
# use std::cmp;
entities.sort_unstable_by(
|(lh_pos, _, _), (rh_pos, _, _)| lh_pos.y.partial_cmp(&rh_pos.y).unwrap()
);
// See individual structs for more methods.
Nightly
此crate对分配和内存布局有严格的要求,因此需要以下nightly功能
- allocator_api
- alloc_layout_extra
链接
许可证
相关
如果你喜欢这个,你可能还会喜欢以下Zac Burns (That3Percent)编写的其他crate
- second-stack Rust内存分配器,用于大型切片,这些切片不会逃离栈。
- js-intern 存储每个不同的JavaScript原型的唯一副本
- js-object 创建JavaScript对象的宏
依赖项
~17KB