39 次发布

0.8.4 2024年6月22日
0.7.5 2024年4月10日
0.7.4 2023年10月28日
0.7.1 2023年6月18日
0.3.4 2018年2月27日

#10 in 缓存

Download history 29549/week @ 2024-05-04 33051/week @ 2024-05-11 26470/week @ 2024-05-18 22438/week @ 2024-05-25 25631/week @ 2024-06-01 25883/week @ 2024-06-08 30021/week @ 2024-06-15 30299/week @ 2024-06-22 21807/week @ 2024-06-29 24602/week @ 2024-07-06 25965/week @ 2024-07-13 27250/week @ 2024-07-20 27502/week @ 2024-07-27 26943/week @ 2024-08-03 29150/week @ 2024-08-10 21964/week @ 2024-08-17

110,964 每月下载量
161 个 Crates 中使用 (10 个直接使用)

MIT/Apache

110KB
2.5K SLoC

Internment — 最新版本 文档 Windows 构建状态 覆盖状态

更新日志

一个用于在 Rust 中归一化字符串或其他数据的非常容易使用的库。归一化数据在哈希或比较等价性(只是指针比较)方面非常高效。数据也会自动去重。

使用 internment crate 有三种选择

  1. Intern,它永远不会释放你的数据。这意味着 InternCopy,所以你可以免费制作尽可能多的指针副本。其实现也不使用不安全代码。

  2. ArcIntern,它引用计数你的数据,当没有更多引用时释放它。 ArcIntern 将保持内存使用量低,但在创建你的指针副本或丢弃指针时使用原子递增/递减。需要功能 arc

  3. ArenaIntern,它在 Arena 中存储其数据,当释放 arena 本身时释放数据。需要功能 arena

在每种情况下,访问你的数据都是一个指针解引用,任何归一化数据结构(InternArcInternArenaIntern)的大小都是一个指针。在每种情况下,你都有保证单个数据值(由 EqHash 定义)将对应单个指针值。这意味着我们可以使用指针比较(和指针哈希)来代替值比较,这非常快。

此外,请注意,如果您不使用 Intern 类型,您可能希望使用以下命令编译:cargo build --no-default-features --features arc(或 arena),这将略微加快您的构建速度并减小可执行文件的大小。

示例

use internment::Intern;
let x = Intern::new("hello");
let y = Intern::new("world");
assert_ne!(x, y);
println!("The conventional greeting is '{} {}'", x, y);

Arena 示例

use internment::Arena;
let arena: Arena<&'static str> = Arena::new();
let x = arena.intern("hello");
let y = arena.intern("world");
assert_ne!(x, y);
println!("The conventional greeting is '{} {}'", x, y);

与其他 Intern 库的比较

crates.io 上已经有一些可用的 Intern 库。那么 internment 有什么不同之处?许多 Intern 库都是特定于字符串的。通用目的的 Intern 库包括:

  1. symtern

  2. shawshank

  3. intern,这是一个正在进行中的项目。

这些库都实现了 arena 分配,使用各种大小的令牌来引用 interned 对象。这种方法使得它们的使用远比 internment 更具挑战性。它们的方法还允许在超出作用域时一次性释放所有 interned 对象(这是一个优点)。

相对于 internment 的方法,arena 分配的主要缺点是:

  1. 令牌的查找可能会失败,这可能是因为手动生成无效的令牌,或者一个池中的令牌被另一个池使用。这给使用 interned 对象的代码添加了一个不安全因素:要么它们假设没有错误并遇到错误时崩溃,要么它们在所有使用令牌的地方都有错误处理。

  2. 如果使用多个池,令牌的查找可能会给出错误的对象。如果您避免使用多个池,这很容易避免,但您可能不会从 arena 分配中获得太多好处。

  3. 令牌的查找速度较慢。虽然它们都宣传速度快,但任何查找都将比指针解引用慢。公平地说,增加内存局部性原则上可能在某些访问模式中使令牌查找更快,但我怀疑这一点。

为了平衡这一点,因为 internment 有全局有效的令牌,它使用一个 Mutex 来保护其内部数据,在 intern 新数据时进行,这可能比其他 intern 库慢(除非您想要在线程间使用它们的令牌,在这种情况下,您必须将池放入 Mutex 中并支付相同的代价)。

另一个与 internment 非常相似的 Intern 库是:

  1. hashconsing

hashconsing 库在 API 上比 internment 更复杂,但以类似的方式生成全局指针。数据类型 HConsed<T> 总是使用 Arc 进行引用计数,这使得它与 ArcIntern 类似,但效率低于 Intern,但不会永久泄漏内存。

依赖项

~1.4–7MB
~41K SLoC