我查看了 的源代码String,发现它是根据 实现的Vec,它没有任何形式的小对象优化:
pub struct String {
vec: Vec<u8>,
}
Run Code Online (Sandbox Code Playgroud)
来自 C++,其中每个主要标准库都使用短字符串优化 (SSO) std::string,这是非常令人惊讶的。字符串的许多用例都涉及非常短的字符串,例如:
"==", "pub","delete"setting: enabled鉴于此,默认情况下不使用任何 SSO 的理由是什么String?是否可以追溯添加该功能?是否有任何分析数据可以证明 SSO 是否有帮助?
SSO 是通过重用容器的内存来完成的std::string,否则容器将存储指针、大小和容量来存储:
也有可能只重用容量,并且有一个指向字符串对象内部的指针。所有这些通常都是通过 , 完成的union,并且在 Rust 中也是可能的。
SSO 并不总是成功 - 它以牺牲长字符串为代价来优化短字符串。Rust 更喜欢具有一致的性能特征,尤其是在标准库中,并让外部板条箱处理其他情况。这样,标准库的用户就不会感到悲观,如果需要,他们可以使用外部板条箱,并且仍然享受针对其特定用例的优化。
此外,Rust 中的 SSO 可能比 C++ 中的 SSO 更昂贵:虽然我不知道 C++ 中的标准库是否实际使用此功能,但 C++ 具有移动构造函数 - 因此,可以有一个指向数据的指针,无论数据存储在堆或堆栈。这样,访问数据就可以无分支了。然而,Rust 无法做到这一点,因为当对象移动时,指向内联存储的指针必须更新 - 但在 Rust 中,移动始终是简单的 memcpy。
此外,虽然 Rust 可以定义String具有 SSO,但现在这是不可能的,因为它保证缓冲区将始终存储在堆上,并且String::into_bytes()(返回Vec<u8>)保证不复制数据。