3个版本 (重大变更)
0.3.0 | 2022年4月8日 |
---|---|
0.2.0 | 2022年4月7日 |
0.1.0 | 2022年4月7日 |
#368 in 内存管理
54KB
835 行
RefBox
一个具有弱引用的Box
。
RefBox
是一个拥有数据的智能指针,就像标准的Box
。同样,RefBox不能廉价地克隆,当它被丢弃时,它指向的数据也会被丢弃。然而,一个RefBox可以有指向同一数据的许多Ref
指针。这些指针不拥有数据,并且是引用计数的,类似于标准库中的Weak
。这意味着,只要RefBox存在,Refs就可以从多个地方访问数据,而不需要生命周期参数。
在只有一个Rc且许多Weak指向同一数据的情况下,RefBox可以看作是标准库中的Rc
、Weak
和RefCell
组合的一个较轻的替代方案。
RefBox不会区分强指针和弱指针以及不可变借用和可变借用。始终只有一个强指针、零个、一个或多个弱指针,并且所有借用都是可变的。这意味着在任何给定时间只能有一个借用处于活动状态。但作为回报,RefBox占用的内存更少,从RefBox借用更快,并且Ref不需要升级到RefBox才能访问数据。
注意:此crate目前为实验性。
Rc 与 RefBox
Rc<RefCell<T>> |
RefBox<T> |
|
---|---|---|
指针类型 | 许多强指针和许多弱指针 | 一个强所有者和许多弱指针 |
可克隆 | 两者Rc 和Weak 都易于克隆 |
只有Ref 可以廉价地克隆 |
升级/降级 | Rc 可降级,Weak 可升级 |
没有升级或降级,但有RefBox::create_ref |
数据访问 | RefCell::try_borrow_mut |
RefBox::try_borrow_mut |
弱数据访问 | 1. Weak::upgrade 2. RefCell::try_borrow_mut 3. Rc::drop |
Ref::try_borrow_mut |
活跃借用 | 一个可变或多个不可变 | 一个(可变或不可变) |
T::drop |
当所有 Rc 都被释放时 |
当所有者 RefBox 被释放时 |
最大 Weak 数量 |
usize::MAX |
u32::MAX |
堆开销 | 64位:24字节 32位:12字节 |
8字节 |
性能 | 克隆速度快,修改速度慢 | 克隆引用稍微慢一些,修改速度很快 |
示例
use refbox::RefBox;
fn main() {
// Create a RefBox.
let owner = RefBox::new(100);
// Create a weak reference.
let weak = owner.create_ref();
// Access the data.
let borrow = weak.try_borrow_mut().unwrap();
assert_eq!(*borrow, 100);
}
性能比较
包含了一些基准测试,用于比较 RefBox
与 Rc
的性能。每个基准测试都遵循相同的流程
- 创建一个
Rc
或RefBox
,可选地包含一个弱引用; - 执行一个操作 x 次数;
- 释放 Rc 或 RefBox。
水平轴显示操作执行的次数。垂直轴显示完成上述整个过程的平均时间。
基准测试在 HP Intel Core i7-7700HQ CPU @ 2.80GHz,Windows 10 64位系统上执行。鼓励您自己进行基准测试。
通过所有者进行修改耗时较少(只有 ~80%)
通过弱引用进行修改耗时更少(只有 ~36%)
然而,创建、克隆和释放弱引用需要更多一点时间
许可
在以下任一许可下发布
- Apache License, Version 2.0 (LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT 许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
任选其一。
贡献
除非您明确声明,否则您提交的任何有意包含在作品中的贡献,根据 Apache-2.0 许可证定义,应以上述双重许可发布,不附加任何额外条款或条件。