#reference-counting #rc #arc #garbage-collection #biased-rc

no-std hybrid-rc

线程安全的混合引用计数指针

7个版本 (破坏性)

0.6.0 2022年2月11日
0.5.0 2022年2月1日
0.4.0 2021年11月17日
0.3.0 2021年11月13日
0.1.1 2021年10月31日

#393 in 内存管理

每月下载 24

MPL-2.0 许可证

115KB
2K SLoC

hybrid-rc - 线程安全的混合引用计数指针

Crates.io Documentation License Build Status Test Coverage

用法

  1. 将以下内容添加到您的Cargo.toml
[dependencies]
hybrid-rc = "0.5.0"
  1. 阅读crate文档

功能

hybrid-rc crate提供了泛型类型HybridRc<T, State>Weak<T>用于引用计数指针。

它基于"偏斜引用计数:在垃圾回收中减少原子操作" 中描述的算法,但适应了Rust的类型系统和其缺乏托管运行时环境。

原子和非原子引用计数的切换通过类型系统管理

  • HybridRc<T, Local>(类型别名为Rc):非常快,但仅适用于一个线程。
  • HybridRc<T, Shared>(类型别名为Arc):较慢,但适用于所有情况。

两种变体的实例可以相互转换。特别是,可以使用 HybridRc::to_shared(&rc).into()Rc 转换为 Arc。另一方面,如果没有其他线程持有相同值的 Rc,则可以使用 HybridRc::to_local(&arc).try_into()Arc 转换为 Rc

任务

  • 实现了所有稳定的 Rc/Arc 功能
    • 新功能()
    • as_ptr()
    • get_mut()
    • get_mut_unchecked()
    • make_mut()
    • into_raw()
    • from_raw()
    • pin()
    • try_unwrap()
    • weak_count()
    • strong_count()
    • [in|de]crement_strong_count()(作为 increment_shared_strong_count() 等)
    • ptr_eq()
    • downcast()
    • impl AsRef
    • impl Borrow
    • impl Clone
    • impl Debug
    • impl Default
    • impl Deref
    • impl Display
    • impl Drop
    • impl From<&[T]>
    • impl From<&str>
    • impl From<String>
    • impl From<Box<T>>
    • impl From<Cow<'a, T>
    • impl From<T>
    • impl From<Vec<T>>
    • impl FromIterator
      • TrustedLen 的特殊化
    • impl Into<Waker>
    • impl Hash
    • impl Ord
    • impl PartialEqimpl Eq
    • impl PartialOrd
    • impl Pointer
    • deref()borrow()as_ref()
    • 弱指针(downgrade()upgrade()
  • 在本地和共享的 HybridRc 之间进行转换
    • to_shared()to_local()
    • impl Fromimpl TryFrom
  • 便利的类型别名
  • 无尺寸强制转换
    • 使用 FromHybridRc<dyn Any, _> 升级
    • 使用 FromHybridRc<[T; N], _> 转换为 HybridRc<[T], _>
  • 最小化内存开销
  • 支持创建循环引用 (new_cyclic())
  • 完全支持 Pin(包括升级/降级到 PinWeak

性能

Rc::clone()Arc::clone() 以及 Rc::drop()Arc::drop() 的运行时间几乎与它们的标准库对应版本相同。

Weak 引用模仿了 std::sync::Weak,因此始终使用原子操作。与标准库的对应版本相比,Weak::clone() 和升级到 Arc 会稍微慢一些。Weak::upgrade_local() 比比 Weak::upgrade() 约慢 15%。

Rc::to_shared() 的成本几乎与 Arc::clone() 相同,而 Arc::to_local() 的成本大约与 Weak::upgrade() 相同。

每个分配的内存开销大约是标准库对应版本的两倍,以容纳额外的引用计数和拥有线程的线程 ID(在 x86_64 上,每个分配为 32 字节)。指针对象本身的大小与 NonNull<T> 相当。

示例基准测试

在英特尔酷睿 i7-4790K 上执行的基准测试。仅供参考。

std::rc::Rc HybridRc<T, Local> HybridRc<T, Shared> std::sync::Arc
clone() 1.5 纳秒 1.5 纳秒 5.0 纳秒 5.0 纳秒
drop() 1.5 纳秒 1.6 纳秒 4.6 纳秒 6.3 纳秒
to_local() 8.2 纳秒
to_shared() 5.0 纳秒
downgrade() 1.5 纳秒 8.0 纳秒 8.0 纳秒 7.8 纳秒
upgrade*() 1.6 纳秒 9.4 纳秒 8.2 纳秒 8.0 纳秒

no_std 支持

此包为 no_std 环境提供有限支持。在此模式下,只有当 任何 线程上都没有 Rc 时,Arc::to_local()Weak::upgrade_local() 才能成功,因为如果没有 std,则无法可靠地识别线程。

要启用 no_std 模式,请在 Cargo.toml 中禁用默认启用的 std 功能。需要全局分配器。

支持的 Rust 版本

支持的最小 Rust 工具链版本是 Rust 1.55.0

支持 no_std 功能的最小 Rust 工具链版本是 Rust 1.56.0

稳定性

此包遵循 语义版本控制,并额外承诺在 1.0.0 以下不会引入向后不兼容的更改,仅通过更改补丁级别版本号。

许可

遵循 Mozilla 公共许可证,版本 2.0 (LICENSEhttps://www.mozilla.org/en-US/MPL/2.0/).

贡献

除非您明确表示,否则您有意提交给工作以供包含的贡献将按照上述许可进行,包括与二级许可证的兼容性,如 MPL 所定义。

无运行时依赖