17 个版本
0.5.2 | 2022 年 5 月 27 日 |
---|---|
0.5.1 | 2021 年 7 月 22 日 |
0.5.0 | 2021 年 1 月 26 日 |
0.4.4 | 2020 年 5 月 2 日 |
0.4.2 | 2020 年 3 月 31 日 |
#34 在 Rust 模式 中
638,543 每月下载量
在 503 个 crate 中使用 (36 直接使用)
40KB
894 行
beef
比原始的 Cow
更快、更紧凑的实现。
use beef::Cow;
let borrowed: Cow<str> = Cow::borrowed("Hello");
let owned: Cow<str> = Cow::owned(String::from("World"));
assert_eq!(
format!("{} {}!", borrowed, owned),
"Hello World!",
);
此 crate 公开了 Cow
的两个版本
beef::Cow
是 3 个字宽:指针、长度和容量。它将所有权标签存储在容量中。beef::lean::Cow
是 2 个字宽,将长度、容量和所有权标签都存储在一个字中。
这两个版本都比 std::borrow::Cow
更简洁。
use std::mem::size_of;
const WORD: usize = size_of::<usize>();
assert_eq!(size_of::<std::borrow::Cow<str>>(), 4 * WORD);
assert_eq!(size_of::<beef::Cow<str>>(), 3 * WORD);
assert_eq!(size_of::<beef::lean::Cow<str>>(), 2 * WORD);
它是如何工作的?
标准库中的 Cow
是一个包含两个变体的枚举
pub enum Cow<'a, B> where
B: 'a + ToOwned + ?Sized,
{
Borrowed(&'a B),
Owned(<B as ToOwned>::Owned),
}
对于最常见的值对 - &str
和 String
,或 &[u8]
和 Vec<u8>
- 这意味着整个枚举是 4 个字宽
Padding
|
v
+-----------+-----------+-----------+-----------+
Borrowed: | Tag | Pointer | Length | XXXXXXXXX |
+-----------+-----------+-----------+-----------+
+-----------+-----------+-----------+-----------+
Owned: | Tag | Pointer | Length | Capacity |
+-----------+-----------+-----------+-----------+
而不是使用带有标签的枚举,beef::Cow
使用容量来确定它所持有的值是拥有(容量大于 0)还是借用(容量为 0)。
beef::lean::Cow
甚至更进一步,将长度和容量放在一个 64 字中。
+-----------+-----------+-----------+
beef::Cow | Pointer | Length | Capacity? |
+-----------+-----------+-----------+
+-----------+-----------+
beef::lean::Cow | Pointer | Cap | Len |
+-----------+-----------+
任何拥有0容量的Vec
或String
都被视为借用的值。因为没有容量意味着指针后面没有实际分配,所以这是安全的。
基准测试
cargo +nightly bench
获取&str
引用的微基准测试非常不稳定,你可能会得到截然不同的结果。一般来说,以下情况似乎成立:
beef::Cow
和beef::lean::Cow
在获取引用&T
方面比std::borrow::Cow
更快。这是有意义的,因为我们避免了枚举标签分支。- 3字节的
beef::Cow
在创建借用变体时更快,但在创建所有者变体时比std::borrow::Cow
慢。 - 2字节的
beef::lean::Cow
在这两方面都更快。
running 9 tests
test beef_as_ref ... bench: 57 ns/iter (+/- 15)
test beef_create ... bench: 135 ns/iter (+/- 5)
test beef_create_mixed ... bench: 659 ns/iter (+/- 52)
test lean_beef_as_ref ... bench: 50 ns/iter (+/- 2)
test lean_beef_create ... bench: 77 ns/iter (+/- 3)
test lean_beef_create_mixed ... bench: 594 ns/iter (+/- 52)
test std_as_ref ... bench: 70 ns/iter (+/- 6)
test std_create ... bench: 142 ns/iter (+/- 7)
test std_create_mixed ... bench: 663 ns/iter (+/- 32)
许可协议
此软件包根据MIT许可协议和Apache License(版本2.0)的条款进行分发。请选择最适合您的一个。
有关详细信息,请参阅LICENSE-APACHE和LICENSE-MIT。
依赖项
~180KB