#弱引用 #智能指针 #指针 # #引用 #引用数据 #智能

refbox

一个拥有单个所有者和多个弱引用的智能指针

3个版本 (重大变更)

0.3.0 2022年4月8日
0.2.0 2022年4月7日
0.1.0 2022年4月7日

#368 in 内存管理

MIT/Apache

54KB
835

RefBox

一个具有弱引用的Box

RefBox是一个拥有数据的智能指针,就像标准的Box。同样,RefBox不能廉价地克隆,当它被丢弃时,它指向的数据也会被丢弃。然而,一个RefBox可以有指向同一数据的许多Ref指针。这些指针不拥有数据,并且是引用计数的,类似于标准库中的Weak。这意味着,只要RefBox存在,Refs就可以从多个地方访问数据,而不需要生命周期参数。

在只有一个Rc且许多Weak指向同一数据的情况下,RefBox可以看作是标准库中的RcWeakRefCell组合的一个较轻的替代方案。

RefBox不会区分强指针和弱指针以及不可变借用和可变借用。始终只有一个强指针、零个、一个或多个弱指针,并且所有借用都是可变的。这意味着在任何给定时间只能有一个借用处于活动状态。但作为回报,RefBox占用的内存更少,从RefBox借用更快,并且Ref不需要升级到RefBox才能访问数据。

注意:此crate目前为实验性

Rc 与 RefBox

Rc<RefCell<T>> RefBox<T>
指针类型 许多强指针和许多弱指针 一个强所有者和许多弱指针
可克隆 两者RcWeak都易于克隆 只有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);
}

性能比较

包含了一些基准测试,用于比较 RefBoxRc 的性能。每个基准测试都遵循相同的流程

  1. 创建一个 RcRefBox,可选地包含一个弱引用;
  2. 执行一个操作 x 次数;
  3. 释放 Rc 或 RefBox。

水平轴显示操作执行的次数。垂直轴显示完成上述整个过程的平均时间。

基准测试在 HP Intel Core i7-7700HQ CPU @ 2.80GHz,Windows 10 64位系统上执行。鼓励您自己进行基准测试。

通过所有者进行修改耗时较少(只有 ~80%)

Benchmark: mutate through owner, RefBox is faster.

通过弱引用进行修改耗时更少(只有 ~36%)

Benchmark: mutate through weak reference, RefBox is much faster.

然而,创建、克隆和释放弱引用需要更多一点时间

Benchmark: create and drop first reference, Rc is slightly faster.

Benchmark: clone and drop references, Rc is slightly faster.

许可

在以下任一许可下发布

任选其一。

贡献

除非您明确声明,否则您提交的任何有意包含在作品中的贡献,根据 Apache-2.0 许可证定义,应以上述双重许可发布,不附加任何额外条款或条件。

无运行时依赖