2 个版本
0.1.1 | 2023年12月16日 |
---|---|
0.1.0 | 2023年12月2日 |
#495 在 内存管理
21KB
256 行
ref_arena
A no_std
(alloc) 池,其行为类似于 Slab<Rc<T>>
,但性能更好且功能更少。
此池将引用计数与对象存储在连续的缓冲区中,这减少了多次小内存分配的需求。引用可以被克隆,并像正常的 Rc
一样操作。当所有指向对象的引用都释放后,空间将可用于新的对象,并且如果池被释放,底层的缓冲区也可能被释放。
此池具有恒定时间插入、解引用和删除功能,在分配较少的情况下降低内存碎片,提高了性能(取决于分配器),并可能使用更少的内存。
RefArena
不支持弱引用,并且在未来可能不会支持。
此库使用了相当数量的不安全代码,并部分通过 miri 进行测试。由于代码不是太复杂,应该是安全的,但请注意潜在的错误。
示例
use ref_arena::{RefArena, RcRef};
let mut arena: RefArena<i32> = RefArena::new();
// Create a reference
let reference: RcRef<i32> = arena.insert(5);
// Deref to get the inner value
let inner = *reference;
assert_eq!(inner, 5);
// We can create clones of the reference just like an Rc!
let clone = reference.clone();
assert_eq!(*clone, 5);
// References can be held even after the arena is dropped.
drop(arena);
assert_eq!(*reference, 5);
// Objects (and internal buffers) are dropped when
// all references are dropped.
drop(reference);
drop(clone);
基准测试
注意:这些基准测试非常具体,旨在创建大量小型对象。
此外,这些基准测试可能会因系统和分配器而异。
分配 10k 个 Rc
std::rc::Rc allocate 10_000 247.59 μs
RefArena allocate 10_000 48.57 μs
~5x speedup
解引用 10k 个 Rc
std::rc::Rc deref 10_000 4.97 μs
RefArena deref 10_000 4.86 μs
no speedup
解引用应该在两者之间大约相同,因为它是一个简单的指针解引用。
释放 10k 个 Rc
std::rc::Rc drop 10_000 134.35 μs
RefArena drop 10_000 29.06 μs
~4.62x speedup
重新分配 10k 个 Rc
RefArena realloc 10_000 45.62 μs
在这种情况下,10k 个 RcRef
被分配和释放,我们测量将 10k 个对象放回池中所需的时间。(与分配进行比较)
与 rc_arena
的比较
rc_arena
与 ref_arena
类似,因为它们都是返回引用计数的池。两者都包含内部缓冲区,其中包含对象的连续列表。
两者之间的主要区别在于 rc_arena
不单独计数对象。当 ref_arena
中的对象的所有引用都释放时,内部对象将被释放,空间将可用于新的插入(类似于 slab
和 stable-vec
),而在 rc_arena
中,空间永远不会再次可用。
rc_arena
在需要引用计数的对象数量确定时非常有用,而ref_arena
在频繁创建和删除对象时更为适用。
请注意,这个比较可能并不完全准确,因为这仅是从代码和文档中能得知的信息。此外,这个crate并非专门为rc_arena
而制作的。
许可证:MIT