2021 年,Python 又获得了 TIOBE 年度编程语言,排名已经是第一。而 Rust 依然在 20 名以外。但依然有人认为,Rust 甚至可能取代 Python。不过这不重要,认清两者的优缺点,进而合适的地方使用合适的语言,这才最重要。
在这个指南中,我们将比较 Rust 和 Python 这两门语言,同时将讨论它们各自的应用场景,回顾使用 Rust vs. Python 的优缺点,并解释 Rust 为什么越来越受欢迎(甚至可能取代 Python)。
01 Rust 是什么?
Rust [1] 是一门系统编程语言,专注于安全,尤其是并发安全,支持函数式和命令式以及泛型等编程范式的多范式语言。Rust 在语法上和 C++ 类似,但是设计者想要在保证性能的同时提供更好的内存安全。Rust 最初是由 Mozilla 研究院的 Graydon Hoare 设计创造,然后在 Dave Herman, Brendan Eich 以及很多其他人的贡献下逐步完善的。Rust 的设计者们通过在研发 Servo 网站浏览器布局引擎过程中积累的经验优化了 Rust 语言和 Rust 编译器。
Rust 拥有 优秀的文档 [2] 、友好的编译器和有用的错误消息,以及顶级工具,包括集成包管理器、构建工具、支持自动完成和类型检查的智能多编辑器、自动格式化程序等等。
Rust 发布于 2010 年。虽然和 Python 相比,Rust 是一门年轻的语言,但是它的社区正在稳步增长。事实上,Rust 已经连续五年(2016,2017,2018,2019,2020)在 Stack Overflow 开发者调查的“最受喜爱编程语言”评选项目中摘取桂冠。
乍一看,Rust 的静态化和强类型化可能看起来有点极端。但从长远来看,这有助于防止意外的代码行为。
02 Python 是什么?
Python [3] 是一门旨在帮助开发人员更有效地工作和更有效地集成系统的编程语言。Python 提供了高效的高级数据结构,还能简单有效地面向对象编程。Python 语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和快速开发应用的编程语言,随着版本的不断更新和语言新功能的添加,逐渐被用于独立的、大型项目的开发。如果速度是最重要的,可以使用较低级别的 API 调用,如 CPython [4] 。
1991 年 Guido van Rossum 推出了 Python,以其代码的可读性、无分号和花括号而著称。
除了可扩展性之外,Python 还是一门解释型语言,这使得它比大多数编译型语言要慢。正如您可能期望的那样,Python 拥有一个庞大的库生态系统和一个庞大的专业社区。
03 什么时候使用 Rust
Rust 被应用于系统开发、操作系统、企业系统、微控制器应用、嵌入式系统、文件系统、浏览器组件、虚拟现实的仿真引擎等。
当性能很重要的时候,Rust 是一种常用的语言,因为它能很好地处理大量数据。它可以处理 CPU 密集型的操作,如执行算法,这就是为什么 Rust 比 Python 更适合系统开发的原因。
Rust 保证了内存的安全性,让你可以控制线程行为和线程之间的资源分配方式。这使你能够构建复杂的系统,也使得 Rust 比 Python 更有优势。
总而言之,你应在以下情况下使用 Rust:
- 你的项目需要高性能
- 你正在构建复杂的系统
- 你重视内存安全而不是简单性
04 什么时候使用 Python
Python 可以用于许多应用领域,从 Web 开发,到数据科学和分析,到 AI 和机器学习,再到软件开发。
Python 被广泛用于机器学习,数据科学和 AI,因为它:
- 简单且容易
- 灵活
- 包含大量面向数据的软件包和库
- 有出色的工具和库生态系统支持
在以下情况下,你应该使用 Python:
- 你需要一种灵活的语言来支持 Web 开发,数据科学和分析以及机器学习和 AI
- 你重视可读性和简单性
- 你需要一种对初学者友好的语言
- 与性能相比,你更喜欢语法简单和开发速度
05 为什么 Rust 可以取代 Python
考虑到 Rust 的迅速普及、受欢迎程度和广泛的使用案例,它几乎不可避免地会在不久的将来超越 Python,以下是一些原因。
性能
Rust 超越 Python 的一个主要原因是性能。因为 Rust 是直接编译成机器代码的,所以在你的代码和计算机之间没有虚拟机或解释器。
与 Python 相比,另一个关键优势是 Rust 的线程和内存管理。虽然 Rust 不像 Python 那样有垃圾回收机制,但 Rust 中的编译器会强制检查无效的内存引用泄漏和其他危险或不规则行为。
编译语言通常比解释语言要快。但是,使 Rust 处于不同水平的是,它几乎与 C 和 C ++一样快,而且没有额外开销。
让我们看一个用 Python 编写的 O(log n) 程序的示例,并使用迭代方法计算完成任务所需的时间:
- import random
- import datetime
- def binary_searcher(search_key, arr):
- low = 0
- high = len(arr)-1
- while low <= high:
- mid = int(low + (high-low)//2)
- if search_key == arr[mid]:
- return True
- if search_key < arr[mid]:
- high = mid-1
- elif search_key > arr[mid]:
- low = mid+1
- return False
输出:
- > python -m binny.py
- It took 8.6μs to search
现在,让我们来看一下使用迭代方法用 Rust 编写的定时 O(log n) 程序:
- >use rand::thread_rng;
- use std::time::Instant;
- use floating_duration::TimeFormat;
- fn binary_searcher(search_key: i32, vec: &mut Vec<i32>) -> bool {
- let mut low: usize = 0;
- let mut high: usize = vec.len()-1;
- let mut _mid: usize = 0;
- while low <= high {
- _mid = low + (high-low)/2;
- if search_key == vec[_mid] {
- return true;
- }
- if search_key < vec[_mid] {
- high = _mid - 1;
- } else if search_key > vec[_mid] {
- low = _mid + 1;
- }
- }
- return false;
- }
- fn main() {
- let mut _rng = thread_rng();
- let mut int_vec = Vec::new();
- let max_num = 1000000;
- for num in 1..max_num {
- int_vec.push(num as i32);
- }
- let start = Instant::now();
- let _result = binary_searcher(384723, &mut int_vec);
- println!("It took: {} to search", TimeFormat(start.elapsed()));
- }
输出:
- > cargo run
- Finished dev [unoptimized + debuginfo] target(s) in 0.04s
- Running target\debug\algo_rusty.exe
- It took: 4.6μs to search
在没有使用任何优化技术的情况下,Rust 和 Python 在同一台机器上执行类似的操作分别需要 4.6 微秒和 8.6 微秒。这意味着 Python 花费的时间几乎是 Rust 的两倍。
内存管理
Python 和大多数现代编程语言一样,被设计成内存安全的。然而,即使没有垃圾回收。Rust 在内存安全方面却让 Python 望尘莫及。
Rust 采用了一种独特的方式来确保内存安全,其中涉及所有权系统和借用检查器(borrow checker)。Rust 的借用检查器确保引用和指针不会超过它们所指向的数据。
错误检查与诊断
Python 和其他语言一样,提供了错误检查和日志机制。但是在让开发者知道哪里出了什么问题的时候,Rust 和 Python 之间有一些差异。
举一个 Python 变量错误的典型例子:
- apple = 15
- print('The available apples are:', aple)
Python 输出:
- Traceback (most recent call last):
- File "binny.py", line 2, in <module>
- print('The available apples are:', aple)
- NameError: name 'aple' is not defined
Rust 中的类似示例:
- fn main() {
- let apple = 15;
- println!("The available apples are:", aple);
- }
Rust 输出:
- println!("The available apples are:", aple);
- ^^^^ help: a local variable with a similar name exists: `apple`
在这里,Rust 推荐了可能的变量,这些变量可能是你想输入的。Python 只会抛出错误,而不会给出如何修复的建议。
再举个例子:
- fn main() {
- let grass = 13;
- grass += 1;
- }
此代码引发错误,因为默认情况下 Rust 中的变量是不可变的。除非它具有关键字 mut ,否则无法更改。
错误:
- let grass = 13;
- | -----
- | |
- | first assignment to `grass`
- | help: make this binding mutable: `mut grass`
修正错误:
- fn main() {
- let mut _grass: i32 = 13;
- _grass += 1;
- }
如你所见,现在它不会引发任何错误。除此之外,Rust 不允许不同的数据类型相互操作,除非将它们转换为相同的类型。
因此,维护 Rust 代码库通常很容易。除非指定,否则 Rust 不允许更改。Python 是允许这种性质的更改的。
与大多数编译语言相比,Rust 因其速度快、内存安全有保证、超强的可靠性、一致性和用户友好性而备受青睐。在编程中,我们已经到了速度开始变得毫不费力的地步。
随着技术的发展,它变得越来越快,试图在更短的时间内做更多的事情,而不需要那么多的权衡。Rust 帮助实现了这一点,同时又不妨碍开发者的工作。当技术试图推动可以实现的边界时,它也会考虑系统的安全性和可靠性,这是 Rust 背后的主要思想。
并行运算
除了速度外,Python 在并行计算方面也有局限性。
Python 使用全局解释器锁(GIL),它鼓励只有一个线程同时执行,以提高单线程的性能。这是一大局限,因为它意味着你不能使用多个 CPU 核进行密集计算。
社区
如前所述,Stack Overflow 的“ 2020 开发人员调查”中有 86%的受访者将 Rust 称为 2020 年最喜欢的编程语言。
同样,“ 2020 HackerRank 开发人员技能报告”的受访者将 Rust 列为他们计划下一步学习的十大编程语言:
相比之下,2019 年的调查将 Rust 排在列表的底部,这表明 Rust 开发人员社区正在迅速增长。
这些数据表明,Rust 正在成为主流开发者社区的一部分。许多大公司都在使用 Rust,一些开发者甚至用它来构建其他编程语言使用的库。著名的 Rust 用户包括 Mozilla、Dropbox、Atlassian、npm 和 Cloudflare 等等。
Amazon Web Service 还对 Lambda,EC2 和 S3 中的性能敏感组件采用了 Rust。在 2019 年,AWS 宣布赞助 Rust 项目,此后为 Rust 提供了 AWS 开发工具包。
公司正越来越多地用更高效的编程语言(如 Rust)取代速度较慢的编程语言。没有其他语言能像 Rust 一样在简单和速度之间做出平衡。
06 总结
Rust 已经发展成为一门易于使用的编程语言,因此它的使用率有所提高。尽管 Python 在机器学习/数据科学社区中占有坚实的地位,但 Rust 在未来很可能被用作 Python 库更有效的后端。
Rust 具有取代 Python 的巨大潜力。目前的趋势是,在应用程序、性能和速度方面,Rust 不仅仅是一种编程语言,它还是一种思维方式。