本文最初发布于 Bitbucket 博客,经原作者 Ash Moosa 授权由 InfoQ 中文站翻译并分享。
这是 Bitbucket 用户 Mohit Agrawal 的客座文章,作为 Bitbucket 写作计划的一部分。
为新产品选择编程语言是一项重要的战略决策。它会影响很多事情,并对招聘、文化甚至产品的可行性都有长期的影响。
首先要考虑的是,你所选择的语言对于要解决的特定问题陈述是否可行。重要的问题如下:
该语言对你的特定用例是否合适?
该语言能够发挥作用吗?
该语言能够在目标平台上运行吗?
这些应该是主要的问题。但也有其他因素可能会影响你的决定,比如:
选择一种特定的语言将如何影响你从理想向现实的换向时间?
使用特定语言的有哪些成本优势?
解决你可能会遇到的问题有多容易?
请牢记这些问题,本文将试图解释我们为新产品选择 Rust 的原因。
用例
我们正在创建一种设备,用于使用来自各种传感器的数据,并通过 Web 和移动应用提供实时分析和智能协助。我们需要一种足够快的语言,以允许最小的实时延迟并使用 SoC 设备的有限资源。
下面是我们评估为项目所选的编程语言的方法。
性能
比较实际应用的跨语言性能是一件很棘手的事情。我们在多种语言方面通常没有同样的专业知识,并且性能还受程序员选择使用的算法和数据结构的影响。但是,正如以下表格的基准所示,一般认为,Rust 的性能与 C++ 相当。并且 Rust 与其他解释器或基于 JIT 的语言(如 Lua 或 Python)相比,性能要好得多。
来源:https://blog.rust-lang.org/2015/04/10/Fearless-Concurrency.html
并发性
正如上面的用例所述,我们希望能够做到实时处理来自多个传感器的数据。我们的目标平台 SoC 设备使用基于 ARM 的 CPU,通常有 4 个以上的内核。我们希望所有的 CPU 内核都能得到利用,这意味着拥有多线程支持非常重要。
Lua 并没有提供原生多线程的支持。尽管有第三方的解决方案,但这些方法的性能和可靠性值得怀疑。另一方面,Rust 内置了对多线程的支持,它的所有权和借用规则帮助我们编写出非常安全的并发代码。
内存安全
动态类型语言提供了很大的灵活性。类型更改不需要通过程序即可进行手动传播。它还提供了更多的思维灵活性,因为你可以在转换、操作和算法方面进行更多的思考。灵活性使你能够更快地移动、更快地更改内容,并以更快的速度进行迭代。但是这些是要付出代价的。人们很容易忽略潜在的问题,而且这些问题通常很难调试。此外,这些特性往往还会带来性能损失。
另一方面,在静态类型语言中,在开发过程的早期阶段捕获大量错误,而且静态类型通常会导致编译代码执行的速度更快,因为当编译器知道正在使用的确切数据类型时,它可以生成优化的机器代码。静态类型还可充当文档。
Rust 超越了这些特点,可谓是青出于蓝而胜于蓝,长江后浪推前浪。Rust 非常严格且学究式的编译器会检查你使用的每个变量以及你引用的每个内存地址。它避免了可能会出现的数据竞争条件,并通知你未定义的行为。
下图的右侧部分显示了并发性和内存安全的问题。这些问题是最复杂的、不可预测的错误类别,并且从根本上来说,不可能被归入 Rust 的安全子集。此外,所有这些类型相关的错误都是危险的,会导致各种安全漏洞。
来源:https://phil-opp.github.io/talk-konstanz-may-2018/#14
类型安全是 Rust 最大的卖点之一,也是 Rust 连续三年在 StackOverflow 调查中成为最受欢迎的语言的原因。
Rust 实现这一效果的方式是通过使用变量所有权的概念。在 Rust 中,每个值都有一个“拥有范围”,传递或返回信息意味着将所有权转移到一个新的范围。你可以借出对你调用的函数的访问,这就是所谓的“借用”。Rust 确保这些租约不会超过被借用的对象的寿命。这不仅使它非常“类型安全”,而且还有助于你正面解决并发问题,因为内存安全和并发错误通常会归结为代码访问数据,而实际上并不应该这样做。
开发者体验
Rust 有一个陡峭的学习曲线。这主要是由于我们上面讨论的“所有权”和“借用”概念所致。这使得 Rust 与 Lua 或 Python 等这样的语言相比,学习起来更困难,也更耗时。它要求开发者非常清楚关于内存分配和并发性的基本计算原则,并且还要求开发者在实现时牢记这些原则。任何语言都应该如此,尤其是在 Rust 语言中,编译器会显式地强制开发者编写最佳的内存安全代码。
尽管开发者正在使用 C++ 进行手工内存管理之类的操作,但 Rust 有很多特定和便利,这些特性和便利让它感觉像是一种高级语言。而且 Rust 有很多抽象概念,这些抽象概念不再让人感觉像是手动内存管理。
低级别控制和高级别安全保证了开发人员能够对性能进行更多的控制,而无需承担学习 C/C++ 的负担,也不必承担出错的风险。
Rust 还通过其强大的库(如 cargo test),方便了开发人员在程序内部编写测试。与 Bitbucket 管道相结合,可以很容易地设置连续集成和可靠地发布代码。
结论
综上所述,Rust 对我们的项目而言是一个很好的选择。当你想要实现资源占用较少的高性能并发系统时,编程语言的选择是有限的。基于解释器的语言在开并发性和低资源环境中往往表现不佳。系统编程语言是这种用例的理想候选语言。
但是,如果没有资源约束,或者不需要高并发性,又或者使用其他机制(如事件循环等)实现高并发性,那么基于解释器的编程语言可能会更好。
C/C++ 是系统编程语言的“圣杯”。但是,在 StackOverflow 的调查中,C 和 C++ 也是最令人畏惧的语言之一,这是有原因的。对于其他高级语言的新程序员来说,接近 C/C++ 很困难。学习曲线非常陡峭。大约有 74 个不同的构建系统和由 28 个不同的包管理器组成的拼凑框架,其中大多数只支持某个平台 / 环境,在该平台之外是毫无用处的。经过三十多年的发展,新程序员已经投入了太多的时间和精力。
另一方面,Rust 相对来说比较容易接近,它还有一个规模相当大的社区,虽然没有像 C/C++ 那样的数十年的技术债务,但也提供了相对的性能。内存安全和更简单的并发性只是附加的好处。
英文原文:
https://bitbucket.org/blog/why-rust
评论 1 条评论