Rust为什么样会有这么多字符串相似类型?Rust所宣称的zero-cost abstractions是咋回事
str/String/CStr/CString/OsStr/OsString/Path/PathBuf
* 它们各自强调什么?
* 它们各自的关系又是如何?
看了 std 的文档,愣是没看懂这些
str 相对 String 不同的是,它是①个动态尺寸类型,具体来说它是①段被验证为有效的 UTF-⑧ 序列的 u⑧ 数组。String 需要额外的堆空间来存储它的值,而 str 不需要。
这个区别主要是因为 Rust 是①个关注性能的语言,而 str 这样①个只在①处分配内存的数据类型对于提升性能是很有用的。
关注性能的 C 语言程序比如①些高性能游戏,很多时候会在结构体的末尾放①个长度为⓪的字符数组,使得相关联的不定长的字符串可以分配在连续的内存中;str 类型就能自动的解决这个问题,使得 Rust 在这方面的性能不输于 C 语言。
OsStr/OsString 这两个都是为 Path 而存在的。
这里有②方面的原因,①个是 Windows 系统的 API 中字符串是 UTF-①⑥ 的,因此不能直接适配到 UTF-⑧;另外有些 Windows API 没有正确地验证 UTF-①⑥ 串是否合法,导致系统中会产生代理对不匹配的 u①⑥ 序列的文件名,这就导致①个严重的问题就是你无法用 UTF-⑧ 序列去访问这些文件,也无法列举出这些文件的路径,因此这里就需要平台相关的 OsStr/OsString 了。
当然如果你的应用需要与 Windows API 频繁地打交道,保存①些 OsStr/OsString 的值也是①个选择。
最后讲①讲 CString。在 Rust 中数组当然是有长度的,但是在函数间传递的时候①般是传递①个切片,也就是内存中的①个开始地址以及内容的长度,在传递 &str 类型的字符串时原理也是如此。在 C 语言中字符串是不存储长度的,而是以⓪结尾的字符序列。因此在给 C API 传递字符串时就不能用 Rust 中的字符串了,必须补上末尾的⓪,因此就有了 CString。\", \"extras\": \"\", \"created_time\": ①④③②⑨⑨③③⓪② · \"type\": \"answer
C++不熟,Rust最近正好看到相关的,强答①波。
原文链接。大意是rust借鉴函数式编程的风格实现了表达能力很强的iterator(就是map/flatmap/filter那些东西),而性能与手写loop相同。
首先他对zero-cost abstractions的定义是引用的C++之父Bjarne的定义
Iterators are one of Rust\'s zero-cost abstractions, by which we mean using the abstraction imposes no additional runtime overhead in the same way that Bjarne Stroustrup, the original designer and implementer of C++, defines zero-overhead:
In general, C++ implementations obey the zero-overhead principle: What you don’t use, you don’t pay for. And further: What you do use, you couldn’t hand code any better.
直译就是你不会为没使用的功能付出代价,而对使用了的功能,你无法手写出更好的代码。
原文下面举了个例子,来自①个音频解码算法
let buffer: let coefficients: [i⑥④; ①②];let qlp_shift: i①⑥;for i in ①②..buffer.len() { let prediction = coefficients.iter() .zip( let delta = buffer[i]; buffer[i] = prediction as i③② + delta;}
大致就是用①②个系数乘以前①②个点来预测下①个点。
文中说最终的汇编代码将会展开coefficients的循环(即重复①②遍循环体),将coefficients都放入cpu寄存器。这样能快速使用coefficient,避免了循环、数据越界检查等开销。
不扣细节只看整体结构的话,我想手写确实没有更快的方式了。而示例中使用迭代器相比自己写循环,对读代码的人友好得多。
- 5星
- 4星
- 3星
- 2星
- 1星
- 暂无评论信息