Rust“巨坑”?真相来了!( 二 )


如果你使用C,你可以使用形式化方法来证明不存在未定义的行为,否则你只能详尽地测试一切 。如果不使用动态内存(切勿调用 free),Ada 是内存安全的 。
Rust 偏偏是成本/安全曲线上的一个有趣的权衡点,但肯定不是唯一的不可替代的点 。
6、工具Rust 工具是值得点赞叫好的 。基线工具、编译器和构建系统(cargo)通常被认为是一流的 。
但是,例如,一些与运行时相关的工具(尤其是堆分析)目前还不存在——如果没有运行时工具,就很难分析程序的运行时 。此外,虽然 IDE 支持不错,但它还远未达到 Java 级别的可靠性 。如今,在 Rust 中不可能自动复杂地重构数百万行程序 。
7、性能“使用 LLVM”并不是解决所有性能问题的通用方法 。虽然我不知道 C++ 和 Rust 的大规模性能基准,但不难列出一些 Rust 不如 C++ 的性能问题 。
最大的一个可能,是 Rust 的移动语义是基于值的(机器代码级别的 memcpy) 。相比之下,C++ 语义使用特殊引用(机器代码级别的指针),可以在其中处理数据 。
理论上,编译器应该能够看穿复制链,但实际上却常常做不到 。要知道,一个相关的问题是不放置新的——Rust 有时需要从堆栈复制字节,而 C++ 可以就地构造东西对象 。
有趣的是,为了使其尽可能高效而不稳定,Rust 的默认 ABI有时比 C 更糟糕 。
图片

Rust“巨坑”?真相来了!

文章插图
最后,虽然理论上 Rust 代码应该由于更丰富的别名信息而更加高效,但启用与别名相关的优化可能会导致 LLVM 错误和错误编译 。
但是,重申一下,这些都是个例,有时的情况恰恰相反 。例如,Rust 的 Box 中不存在 std::unique_ptr 的性能问题 。一个潜在的更大问题是 Rust 的定义时检查泛型不如 C++ 那样富有表现力 。因此,一些高性能的 C++ 模板技巧很难在 Rust 中用漂亮的语法来表达 。
8、不安全(Unsafe)的定义也许跟“所有权”和“借用”相比,更核心的问题是不安全(Unsafe)的边界 。通过界定Unsafe块和函数后面的所有不安全操作,并为它们提供安全的上层接口,可以创建一个兼具以下功能的函数:
一、可解释(非不安全(non-unsafe)的代码不会导致未定义的行为) 。二、模块化(可以单独检查不同的不安全块) 。
显然,这个承诺已经在实践中得到了证实:有bug的 Rust 代码不会造成缓冲区溢出 。
当然,问题没那么简单,也不那么乐观 。
首先,Rust 的内存模型没有定义,因此无法正式检查给定的不安全块是否有效 。对于“rust-c 做什么或可能依赖什么”,有非正式的定义,运行时验证器正在开发中,但实际模型正在不断变化 。因此,可能有一些unsafe的代码,今天虽然在实践中可用,但明天就可能会被声明为无效,并且在明年就会被新的编译器优化所破坏掉 。
其次,据业内开发者的观察结果是,unsafe实际上并不是模块化的 。足够强大的不安全块实际上可以扩展语言 。两个这样的扩展,单独使用时可能没问题,但如果一起使用,可能会导致未定义的行为、观察到的等效性和不安全的代码 。
原文链接:https://medium.com/@kevin_scott_/why-not-rust-1d257c6a07da

【Rust“巨坑”?真相来了!】


推荐阅读