Redian新闻
>
提速40倍!bug更少了,我们用Rust重写了自家项目

提速40倍!bug更少了,我们用Rust重写了自家项目

公众号新闻


作者 | Peefy
译者 | 核子可乐
策划 | 刘燕

如今,Rust 已经悄然成为最具人气的编程语言之一。作为一门新兴的系统语言,Rust 天然具备内存安全机制、与 C/C++ 相近的性能优势、出色的开发者社区,以及完备的说明文档、工具链和 IDE 体验等。

在本文中,我们将介绍如何使用 Rust 改写项目,逐步实现生产环境。讲解改写中为何选择 Rust,实际遇到的问题以及使用 Rust 改写后的真实效果。

我们用 Rust 开发的这个项目名叫 KCL。KCL 是一种基于约束的记录与函数开源语言。KCL 通过成熟的编程语言技术和实践改进了大量复杂的配置编写,强调以配置为基础构建起更好的模块化、扩展性和稳定性,降低逻辑编写难度,同时改善自动化与生态扩展能力。

KCL 之前一直用 Python 进行编写。

考虑到用户体验、性能和稳定性等因素,我们决定用 Rust 进行重写,并由此获得了以下提升:

  • 凭借 Rust 强大的编译检查和错误处理功能,现在 KCL 的 bug 更少了。

  • 语言端到端编译和执行性能提高了 66%。

  • 语言前端解析器性能提升达 20 倍。

  • 语言语义分析器的性能提高达 40 倍。

  • 语言编译器在编译过程中,平均内存使用量仅为原始 Python 版本的一半。

我们遇到了哪些问题?

编译器、构建系统和运行时都能在 Rust 社区里找到定位相近的现成方案,例如 deno、swc、turbopack 和 rustc 等。我们使用 Rust 完整构建了编译器的前、中和运行时,取得的效果比一年前用 Python 的时候更好。

一年前,我们使用 Python 构建了 KCL 编译器的整个实现。虽然刚开始跑得不错,Python 简单易用、生态丰富且团队研发效率也高,但随着代码膨胀和工程师数量的增加,Python 代码的维护开始变得愈发困难。

虽然我们强制要求在项目中编写 Python 类型注释,也采用了更严格的 lint 工具,并将代码测试行的覆盖率设定在了 90% 以上,但仍然挡不住种种运行时错误。比如 Python None 空对象、找不到属性等等。我们在重构 Python 代码时总得小心谨慎,这已经严重影响到了用户体验。

此外,由于 KCL 的用户以开发者为主,所以编程语言或编译器的任何内部实现错误都是不可接受的,这同样给我们的用户体验带来了大麻烦。Python 编写的程序启动缓慢,性能也无法满足自动化系统在线编译执行的效率需求。因为在我们的场景中,用户希望能在修改 KCL 代码之后,快速查看编译结果。很明显,用 Python 编写的编译器没办法满足这方面的要求。

为什么选择 Rust

我们选择 Rust 的理由如下:

  • 我们曾使用 Python、Go 和 Rust 实现了一个简单的编程语言栈虚拟机,并进行了性能比较。在此场景下,Go 和 Rust 的性能差不多,Python 则明显落后一些。综合考虑之后,我们决定选择 Rust。三种语言的栈虚拟机实现代码在此: https://github.com/Peefy/StackMachine。

  • 越来越多的编程语言编译器或运行时,特别是前端基础设施项目,开始用 Rust 进行编写或重构。此外,Rust 还广泛出现在基础设施、数据库、搜索引擎、网络、云原生、UI、嵌入式等领域。从这个角度看,Rust 语言的可行性和稳定性至少有所保障。

  • 考虑到后续项目开发将涉及到区块链和智能合约方向,我们发现社区中有大量区块链和智能合约项目都是用 Rust 编写的。

  • 使用 Rust 可以带来更好的性能和稳定性,让系统更易于维护且更加健壮。另外,Rust 还可以通过 FFI 对外开放 C API,借此实现多语言使用与扩展、方便生态融合。

  • Rust 能够很好地支持 WASM。目前社区中有很多 WASM 生态系统都是由 Rust 构建而成。KCL 语言和编译器可以由 Rust 编译为 WASM,进而在浏览器中运行。

基于上述理由,我们最终选择了 Rust 而非 Go。在整个重写过程中,我们发现 Rust 的综合素质确实非常优秀(性能高、抽象度好)。虽然某些语言特性还不完善,比如生命周期上会带来一定额外成本且生态不够丰富,但 Rust 仍给我们留下了深刻印象。

使用 Rust 有哪些难点

虽然我们决定用 Rust 重写整个 KCL 项目,但大多数团队成员还没有用 Rust 编写项目的经验。我之前学过 Rust 语言,依稀记得大概学到 Rc 和 RefCell 就放弃了,当时也从没想到 Rust 会跟 C++ 有那么多相似之处。

使用 Rust 的风险,主要体现在 Rust 语言的学习成本上,不少博文都提到过这个问题。由于 KCL 项目的整体架构并没有太大变化,只是针对 Rust 做出子正经模块设计和编码优化,所以我们的重写工作基本就是以边做边学的方式在进行。

刚开始使用 Rust 编写整个项目时,我们花了不少时间研究查询、编译和调试方面的知识。但随着项目推进,我们发现 Rust 开发的最大难题主要集中在思路转变和开发效率上。

思路转变

首先,Rust 的语法和语义很好地吸纳并整合了函数式编程中的类型系统相关概念,例如抽象代数类型(ADT)。

另外,Rust 中没有“继承”的概念。如果没法理解这些,即使是其他语言中非常普通的结构定义,在 Rust 中也可能会占用我们大量时间。例如,以下 Python 代码在 Rust 中就需要改写成后面的形式:

  • Python

from dataclasses import dataclassclass KCLObject:    pass@dataclassclass KCLIntObject(KCLObject):    value: int@dataclassclass KCLFloatObject(KCLObject):    value: float
  • Rust

enum KCLObject {    Int(u64),    Float(f64),}


当然,我们在应对 Rust 编译器的错误报告方面也花了不少时间。Rust 编译器确实经常给开发者“找麻烦”,比如抛出借用校验错误。特别是 KCL 编译器,其核心结构是抽象语法树(AST),一种递归嵌套的树结构。

Rust 中有时很难考虑到变量可变性和借用检查之间的关系。以 KCL 编译器中定义的范围结构 Scope 为例,对于存在循环引用的场景,我们要使用 Scope 来展示需要关注的数据依赖性,同时广泛使用 Rust 中的智能指针结构,例如 Rc、RefCell 和 Weak。

/// A Scope maintains a set of objects and links to its containing/// (parent) and contained (children) scopes. Objects may be inserted/// and looked up by name. The zero value for Scope is a ready-to-use/// empty scope.#[derive(Clone, Debug)]pub struct Scope {    /// The parent scope.    pub parent: Option<Weak<RefCell<Scope>>>,    /// The child scope list.    pub children: Vec<Rc<RefCell<Scope>>>,    /// The scope object mapping with its name.    pub elems: IndexMap<String, Rc<RefCell<ScopeObject>>>,    /// The scope start position.    pub start: Position,    /// The scope end position.    pub end: Position,    /// The scope kind.    pub kind: ScopeKind,}
开发效率

Rust 的开发效率可以说是“先抑后扬”。在项目重写之初,如果团队成员之前没接触过函数式编程的概念,不熟悉相关习惯,那 Rust 的开发速度要明显慢于 Python、GO 和 Java 等语言。然而一旦大家熟悉了 Rust 标准库的常见用法和最佳实践,搞定了 Rust 编译器抛出的错误报告,开发效率就会大大提高。在上手之后,Rust 其实更易于写出高质量、安全且高效的本机代码。

例如,我们曾遇到如下所示的 Rust 生命周期错误。在排查了很久之后,我们才发现是忘记标注生命周期参数所引发的生命周期不匹配。此外,Rust 的生命周期与类型系统、作用域、所有权和借用检查等概念耦合起来,确实带来了更高的理解成本和复杂度,其报错信息也不及类型错误那么明显。生命周期不匹配报错中的信息也有点死板,有时会给故障排查增加难度、带来高昂的纠错成本。当然,在熟悉这些概念之后,效率都能有所提高。

struct Data<'a> {    b: &'a u8,}// func2 omit lifecycle parameters, and func2 does not.// The lifecycle of func2 will be deduced as '_ by the Rust compiler by default,// which may lead to lifetime mismatch error.impl<'a> Data<'a> {    fn func1(&self) -> Data<'a> {Data { b: &0 }}    fn func2(&self) -> Data {Data { b: &0 }}}
使用 Rust 的重写收益

经过几个月时间,团队成员们终于用 Rust 完成了项目重写并稳定投入生产环境。回顾整个过程,我们觉得颇有收获。从技术角度来说,重写的过程不仅让我们快速掌握了一门新的编程语言和相关知识,并积极付诸实践。而且,整个重写过程也让我们反思了 KCL 编译器的不合理性并做出修改。在这样一个长周期项目之后,我们发现编译系统更稳定、更安全、代码更清晰、bug 更少而且性能也更高了。

虽然并不是所有模块都实现了 40 倍提速(毕竟有些模块的性能瓶颈不在语言上,比如 KCL 运行时就是内存深拷贝操作),但付出的这些也还是值得的。在使用了一段时间 Rust 之后,思维习惯和开发效率也都不再是问题。

总结

我个人认为,用 Rust 改写项目的最大收获就是让自己又掌握了一门新的编程语言,同时也让我们有机会接触并使用这种势头强劲的语言选项。

在 Rust 的帮助下,我们的 KCL 语言和编译器更加稳定、启动速度和自动化效率都上了新的台阶。KCL 的性能已经优于社区中的其他同类语言,为用户体验带来了显著提升。而这一切都利益于 Rust 的无 GC、高性能、完善错误处理、内存管理、零抽象等特性。各位用户朋友,这是专为你们做的!

最后,如果大家关注 KCL 项目,想要用 KCL 构建自己的场景,或者打算使用 Rust 参与开源项目,欢迎访问https://github.com/KusionStack/community
加入我们的社区大家庭👏👏👏。

原文链接:https://medium.com/@xpf6677/40x-faster-we-rewrote-our-project-with-rust-120b006c6abe

活动推荐

12 月 25-26 日,ArchSummit 全球架构师峰会将落地北京海航万豪酒店。来自百度、京东、华为、腾讯、斗鱼、中国信通院等企业与学术界的技术专家,将就数字化业务架构、低代码实践、国产化替代方案、分布式架构等主题展开分享讨论。

目前已上线数字化场景下的业务架构、低代码实践与应用、国产软件优化迭代之路、多数据中心的分布式架构实践、软件质量保障、技术 - 产品 - 业务、高并发架构实现、架构师成长与团队搭建落地实践、大数据和人工智能融合、大规模微服务架构演进、可观测技术落地、云原生大数据实践等多个专题,点击阅读原文去官网查看大会日程。

会期临近,门票即将售罄,购票或咨询其他问题请联系票务同学:15600537884(微信同电话)

今日荐文

点击下方图片即可阅读

 谷歌员工担心自家 AI 敌不过 ChatGPT,高管回应:其过快发展可能损害公司


你也「在看」吗? 👇

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
硬核观察 #876 数千用 Rust 开发的项目面临拒绝服务攻击酒店Bug价:15美元入住雅高旗下精品酒店,全房型Bug + 含早餐OBS Studio即将支持WebRTC,采用Rust实现英国近3年的学校公寓投诉有3000起与虫相关,其中有272起与Bed Bug相关...遇到了Bed Bug 改怎么办?明星用了翻车的美颜滤镜,我们用正好?华泰【研磨时刻】首秀 | 3000点的财富内耗,我们用什么来治愈?错误的例子证明错误的结论:论“中国队大胜美国队与中国队大败美国队”安省大雪兼狂风 高速400发生连环车祸!十几辆车相撞Bug白菜价!Bose黑五预售!精选翻新无线耳机、音箱、音响等2.2折起!前端又开撕了:用Rust写的Turbopack,比Vite快10倍?雇佣兵是人道援助还是搅动战争大半生就爬過一座山ChatGPT来了,我们都要失业了吗?让三家AI分别写了侦探小说……15年做不好的代码搜索,用Rust重写搞定:GitHub声称能从此“改变游戏规则”[重磅]新变种XBB杀疯!加拿大新冠疫情又反弹!住院率竟是去年同期两倍!新病例少报多达100倍!China’s open-door policy我用 Rust 改写了自己的C++项目:这两个语言都很折磨人!速揽2500星,Andrej Karpathy重写了一份minGPT库比UGG更适合加拿大的寒冬!Sorel雪地靴低至6折!With More People Getting Sick, China’s Restaurants Are Strugglin微软工程师展望Rust 2023:重写编译器、解决管理问题重磅!中国驻美使馆:疫前所发十年签证仍有效但仍暂停使用! 如需赴华可申请半年内2次入境短签!纽约明天或下雪 还有时速40哩强风Fish Shell计划采用Rust重写Linux 6.1正式发布,带有MGLRU、初始Rust支持独家揭秘:Rambus公司用RDRAM标准一统江湖?【机票Bug】国泰直飞 美国回国机票Bug?Shopify开发团队放弃Ruby,改用Node重写CLI工具把代码贴进去自动找bug,这个debug神器自动修复仅需几秒,还有GPT-3在线解惑研究了代码质量后,开发速度提高了 2 倍,bug 减少了 15 倍纽约发出红色预警!预计雨势将为中等至猛烈,还有时速40哩强风...人生如白驹过隙,哪有时间把玩悲剧?以调试 Rust 的方式来学习 Rust | Linux 中国谷歌宣布支持使用Rust开发Chromium如何使用Rust语言设计并开发一个领域编程语言酒店Bug价:6美元入住吴哥窟畔豪华五星级度假酒店,2023年大量日期有Bug
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。