18 个版本
使用旧的Rust 2015
0.4.3 | 2022年3月27日 |
---|---|
0.4.2 | 2021年1月8日 |
0.4.1 | 2018年12月7日 |
0.4.0 | 2017年6月29日 |
0.1.3 | 2015年7月27日 |
#20 in 内存管理
578,818 每月下载量
用于 1,180 个crate (51 直接)
135KB
3.5K SLoC
tendril
警告:此库处于非常早期的开发阶段,其中包含大量unsafe
代码。请自行承担风险!
简介
Tendril
是一种紧凑的字符串/缓冲区类型,针对零拷贝解析进行了优化。藤蔓具有所有权的字符串语义,但有时是共享缓冲区的视图。当你修改藤蔓时,如果需要,将创建一个所有权的副本。进一步的修改将在原地发生,直到字符串变为共享,例如通过 clone()
或 subtendril()
。
通过线程局部(非原子)引用计数来实现缓冲区共享,它具有非常低的开销。Rust类型系统将在编译时防止你将藤蔓在线程之间发送。(下面有关于放宽此限制的想法。)
与在堆中为任何非空字符串分配的 String 不同,
Tendril
可以将小字符串(最多 8 个字节)内联存储,无需堆分配。Tendril
在 64 位平台上也比 String
小——16 个字节比 24 个字节小。Option<Tendril>
的大小与 Tendril
相同,多亏了 NonZero
。
最大 tendril 长度为 4 GB。如果您尝试超过此限制,库将引发 panic。
格式和编码
Tendril
使用 虚类型 来跟踪缓冲区的格式。这确定在编译时,哪些操作可以在给定的 tendril 上使用。例如,Tendril<UTF8>
和 Tendril<Bytes>
可以分别借用为 &str
和 &[u8]
。
Tendril
还与 rust-encoding 集成,并初步支持 WTF-8 缓冲区。
未来计划
绳子
html5ever 将使用 Tendril
作为零拷贝文本表示。保留这种表示一直到 Servo 的 DOM 是一件好事。这将减少内存消耗,并可能加快文本形状和绘制。然而,DOM 文本可能比 4 GB 大,并且无论如何也不会在内存中连续,例如字符实体引用周围。
解决方案: 在这些字符串之上构建一个 rope,并使用它作为 Servo 的 DOM 文本表示。我们也许可以对绳子的不同部分进行并行文本形状和/或绘制。html5ever 还可以将此绳类型用作 BufferQueue
的替代品。
因为底层缓冲区是引用计数的,所以这个绳子的大部分已经是 持久数据结构。考虑将两个绳子附加在一起以获取一个“新”绳子时会发生什么。基于向量的绳子将复制一个小结构体的向量,每个部分一个,并增加相应的引用计数。但它不会复制任何字符串数据。
如果我们想要更多的共享,那么 2-3 finger tree 可能是一个不错的选择。我们可能会继续使用 VecDeque
来处理一定大小以下的绳子。
UTF-16 兼容性
SpiderMonkey 期望大部分文本以 UCS-2 格式存在。在 UTF-8 上实现 JavaScript 字符串的语义很困难。这也适用于通过 document.write
进行 HTML 解析。此外,传递给 SpiderMonkey 的非连续内存字符串将产生额外的开销和复杂性,如果不是完整的复制。
解决方案: 在解析和在 DOM 中使用 WTF-8。Servo 将在必要时 转换为连续的 UTF-16。如果发现一次转换大量文本块是实用的,则转换可以轻松并行化。
源跨度信息
一些html5ever API消费者希望知道每个标记或解析错误的HTML源文件中的原始位置。一个示例应用是一个命令行HTML验证器,其诊断输出类似于rustc
的。
解决方案:接受每个输入字符串的一些元数据。元数据的类型由API消费者选择;默认为()
,大小为零。对于任何非内联字符串,我们都可以提供关联的元数据以及字节数。
依赖关系
~0–1.2MB
~35K SLoC