同时 , 别忘了 , 在 Web 领域 , 很少人具备这种专业知识 , 因为每个人大多都使用非常不同的语言 , 如 JavaScript、Python、Ruby、Elixir 等 。反而Rust 就不会遇到同样的陷阱 , 使开发人员能够以以前的效率水平构建软件 。
Rust 通常会比用于构建 Web 后端的其他技术的性能好几个数量级 , 同时保持显着较低的内存占用 。
当然 , 如果与其他技术相比 , Rust Web 服务器可以在一小部分时间内响应请求 , 这也意味着它可以用更少的服务器响应相同数量的请求 , 这又意味着更少的托管成本 。
这对于中小型产品和公司来说 , 减少托管的云服务器数量 , 就意味每月就可以轻松减少不菲的费用 。
我们的 Python 服务平均约为 50 个请求/秒 , NodeJS 约为 100 个请求/秒 , Rust 约为 690 个请求/秒 。我们可以在通常托管单个 Python 服务的 k8 EKS 节点上安装 4 个 Rust 服务 。——Reddit某用户
然而 , 成本节省还只是好处之一 , 使用更少的服务器也意味着使用更少的能源 。尽管使用可再生能源运行数据中心固然很好 , 但最绿色的能源仍然是我们不使用的能源 。Rust 或许不能解决气候危机 , 但这里要承认的是 , 运行我们编写的软件 , 也会真真切切地消耗资源 , 从而对现实世界产生影响 。软件行业往往会忘记这一点——如果我们能够更有效地利用资源 , 并以更少的投入获得相同的产出 , 这是选择技术时的一个重要考虑 。
2.可靠性和可维护性
虽然性能和效率很重要 , 但在许多情况下 , 可能更相关的原因则是 Rust 的强类型系统所带来的可靠性和可维护性收益 。
像这样的代码片段对于 Web 应用程序(Ruby on Rails)来说是相当典型的:
复制
class User
attr :name
attr :active
attr :activation_date
def activate(activation_date)
self.active = true
self.activation_date = activation_date
save
end
def save
…
end
end
…
user.activate(Time.now)
虽然这段代码非常简洁且易于阅读 , 并且编写这样的代码可以让你快速实现目标 , 但也存在问题 。在这个的示例中 , 虽然我们可以看到用户的属性 , 但我们不知道这些属性周围可能有什么规则(例如 , 如果active是true , 则activation_date可能也必须设置?如果active是false , 则大概activation_date应该是nil?) 。为了验证这些假设 , 我们必须研究该activate方法的实现 , 这意味着需要付出相对较高的努力才能获取信息 。
查看该activate方法的调用 , 我们无法知道它是否会引发错误 , 或者我们应该在哪个时区中度过时间 。虽然 Ruby 可能有点极端 , 但考虑到其众所周知的灵活性 , 许多这些问题在其他语言中也存在 。让我们以 Java 为例 。我们仍然无法在类型系统中对围绕active和activation_date属性的规则进行编码 , 即使可以null , 我们也有NullPointerException在运行时获取 s 的风险 。
随着代码库的增长和开发团队的壮大 , 或者只是随着一些人离开和加入而发生变化 。从事代码库工作的每个人都对整个应用程序以及整个代码库中所做的所有隐式假设都有一个完美的心智模型 , 但这很难做到 , 相反 , 理解这些概念需要人们认真阅读遗留代码 。这不仅降低了效率 , 而且还可能导致生产中的错误率增加 。
与上面相同的代码片段 , 但在 Rust 中更加清晰和富有表现力:
复制
enum User {
Inactive {
name: String,
},
Active {
name: String,
active: bool,
activation_date: DateTime<Utc>,
},
}
impl User {
fn activate(&self, activation_date: DateTime<Utc>) -> Result<(), DBError> {
match self {
User::Inactive { name } => {
let new_user = User::Active {
name: name.clone(),
active: true,
activation_date: activation_date,
};
new_user.save()
}
User::Active { .. } => Err(Error::default()),
}
}
fn save(&self) -> Result<(), DBError> {
…
}
}
首先 , 对于用户模型 , 我们可以使用 Rust 的enum关联数据 。这样 , 就可以完全清楚非活跃用户和活跃用户是什么样子 , 以及在什么场景下可以设置哪些属性——事实上 , 活跃用户和非活跃用户甚至不具有相同的属性 , 但每个用户都只具有对其有意义的属性 。它们代表各自的用户状态 。此外 , 属性的类型也被明确定义——不仅 Rust 是类型化的 , 而 Ruby 显然是非类型化的 , 而且类型也非常精确 , 例如对于字段 , activation_date预期的时区在类型中也是正确的 。
推荐阅读
- 这一次,再多的名和利也救不了李连杰
- 如何区分和田玉和石头
- 私生活混乱?这一次,无论多少的名和利都救不了65岁的赵本山
- 丧夫2个多月,毕夏高调庆32岁生日,和汪峰大笑比V引争议!
- 五行取名带木和火男孩
- 海竿的使用方法和视频 海竿的使用方法
- 黑牡丹花语寓意 牡丹花花语和寓意
- 春节吃汤圆的寓意和象征 春节吃汤圆的寓意
- 关于和田玉,送你5个锦囊,看懂了,可以少走10年的弯路
- 小寒和大寒有多冷