Rust内联数组库inline-array的使用,高效内存布局与固定大小数组操作优化
Rust内联数组库inline-array的使用,高效内存布局与固定大小数组操作优化
主要特性
InlineArray
是一个高度优化的字节数组实现,具有以下特点:
- 栈上仅占用8字节空间
- 7字节及以下的数组直接内联存储在栈上
- 长数组使用两种优化引用计数结构:
- 长度≤255的数组:
AtomicU8
引用计数 +u8
长度字段(仅2字节开销) - 更大数组:
AtomicU16
引用计数 + 48位长度字段
- 长度≤255的数组:
- 引用计数达到最大值时会自动复制数据
内存对齐保证
所有InlineArray
实例都保证存储的数组按8字节边界对齐,这对零拷贝序列化非常重要。
示例代码
use inline_array::InlineArray;
// 创建InlineArray
let ia = InlineArray::from(b"yo!");
// 获取可变引用
let mut_ref = ia.make_mut();
// 克隆数组
let cloned = ia.clone();
// 获取数组长度
let len = ia.len();
// 访问数组元素
let first_byte = ia[0];
完整示例demo
use inline_array::InlineArray;
fn main() {
// 创建短数组(内联存储)
let short = InlineArray::from(b"short");
println!("Short array length: {}", short.len()); // 5
// 创建长数组(堆存储)
let long_data = vec![0u8; 100];
let long = InlineArray::from(&long_data[..]);
println!("Long array length: {}", long.len()); // 100
// 克隆数组(共享数据)
let long_clone = long.clone();
// 修改数组(写时复制)
let mut mutable = long.make_mut();
mutable[0] = 42;
// 检查修改后的值
println!("Modified first byte: {}", mutable[0]); // 42
println!("Original first byte: {}", long[0]); // 0
// 对齐检查
println!("Alignment: {}", std::mem::align_of_val(&*mutable)); // 8
}
其他特性与限制
功能特性:
- 默认禁用的
serde
序列化支持
限制:
- 不支持超过48位长度的数组(最大256TB)
1 回复
Rust内联数组库inline-array的使用指南
概述
inline-array
是一个Rust库,专注于提供高效内存布局的固定大小数组操作。它通过内联存储优化了小数组的性能,避免了堆分配的开销,同时为固定大小数组提供了便捷的操作接口。
主要特性
- 零堆分配的内联存储
- 固定大小数组的高效操作
- 与标准库Vec类似的API体验
- 编译时大小检查
- 针对小数组优化的内存布局
安装
在Cargo.toml中添加依赖:
[dependencies]
inline-array = "0.1"
基本使用
创建内联数组
use inline_array::InlineArray;
// 创建一个可容纳5个元素的内联数组
let mut arr = InlineArray::<i32, 5>::new();
// 从迭代器创建
let arr = InlineArray::from_iter([1, 2, 3].into_iter());
添加和访问元素
let mut arr = InlineArray::<_, 3>::new();
arr.push(1);
arr.push(2);
arr.push(3);
println!("First element: {}", arr[0]); // 访问元素
println!("Array length: {}", arr.len());
数组操作
// 遍历
for item in &arr {
println!("{}", item);
}
// 映射转换
let doubled: InlineArray<_, 3> = arr.iter().map(|x| x * 2).collect();
// 拼接数组
let mut arr1 = InlineArray::from_iter([1, 2].into_iter());
let arr2 = InlineArray::from_iter([3, 4].into_iter());
arr1.extend(arr2);
高级用法
编译时大小检查
// 尝试添加超过容量的元素会在运行时panic
let mut arr = InlineArray::<_, 2>::new();
arr.push(1);
arr.push(2);
// arr.push(3); // 这会panic,因为超过了容量
与标准Vec互转
let arr = InlineArray::from_iter([1, 2, 3].into_iter());
let vec: Vec<_> = arr.into_iter().collect();
let back_to_arr: InlineArray<_, 3> = vec.into_iter().collect();
模式匹配
let arr = InlineArray::from_iter([1, 2, 3].into_iter());
match arr.as_slice() {
[1, 2, 3] => println!("匹配成功"),
_ => println!("不匹配"),
}
性能建议
- 对于小数组(通常小于32个元素),使用
InlineArray
可以获得更好的性能 - 如果数组大小在编译时已知,优先使用
InlineArray
而非Vec
- 避免频繁创建和销毁,复用数组对象
实际应用示例
矩阵运算
type Vector3 = InlineArray<f64, 3>;
fn dot_product(a: &Vector3, b: &Vector3) -> f64 {
a.iter().zip(b.iter()).map(|(x, y)| x * y).sum()
}
let v1 = Vector3::from_iter([1.0, 2.0, 3.0].into_iter());
let v2 = Vector3::from_iter([4.0, 5.0, 6.0].into_iter());
println!("点积结果: {}", dot_product(&v1, &v2));
固定大小缓存
struct RecentItems<T, const N: usize> {
items: InlineArray<T, N>,
}
impl<T, const N: usize> RecentItems<T, N> {
fn push(&mut self, item: T) {
if self.items.len() == N {
self.items.pop();
}
self.items.insert(0, item);
}
}
完整示例demo
use inline_array::InlineArray;
fn main() {
// 示例1: 基本创建和操作
let mut arr = InlineArray::<i32, 5>::new();
arr.push(10);
arr.push(20);
arr.push(30);
println!("数组内容: {:?}", arr.as_slice());
// 示例2: 从迭代器创建
let from_iter = InlineArray::from_iter([1, 2, 3, 4].into_iter());
println!("从迭代器创建的数组: {:?}", from_iter.as_slice());
// 示例3: 数组操作
let doubled: InlineArray<_, 4> = from_iter.iter().map(|x| x * 2).collect();
println!("翻倍后的数组: {:?}", doubled.as_slice());
// 示例4: 向量点积计算
type Vector3 = InlineArray<f64, 3>;
let v1 = Vector3::from_iter([1.0, 2.0, 3.0].into_iter());
let v2 = Vector3::from_iter([4.0, 5.0, 6.0].into_iter());
println!("向量点积结果: {}", dot_product(&v1, &v2));
// 示例5: 固定大小缓存使用
let mut cache = RecentItems::<i32, 3> {
items: InlineArray::new()
};
cache.push(100);
cache.push(200);
cache.push(300);
cache.push(400); // 这会移除第一个元素100
println!("缓存内容: {:?}", cache.items.as_slice());
}
fn dot_product(a: &InlineArray<f64, 3>, b: &InlineArray<f64, 3>) -> f64 {
a.iter().zip(b.iter()).map(|(x, y)| x * y).sum()
}
struct RecentItems<T, const N: usize> {
items: InlineArray<T, N>,
}
impl<T, const N: usize> RecentItems<T, N> {
fn push(&mut self, item: T) {
if self.items.len() == N {
self.items.pop();
}
self.items.insert(0, item);
}
}
这个完整示例展示了inline-array
库的主要功能,包括基本操作、向量计算和缓存实现。你可以直接复制这段代码到你的Rust项目中运行。