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::upgrade2. RefCell::try_borrow_mut3. 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 或 https://open-source.org.cn/licenses/MIT)
任选其一。
贡献
除非您明确声明,否则您提交的任何有意包含在作品中的贡献,根据 Apache-2.0 许可证定义,应以上述双重许可发布,不附加任何额外条款或条件。