背景
多个终端会将其采集的数据以文件的形式上传到服务器的多个目录,然后ETL程序在服务器上定时扫描这些目录,如有新增文件则加载并解析其中的数据,将数据塞入db。因采集频率高,数据文件较多。ETL程序是由python开发,跑一次大概1~2分钟(每5分钟扫描一次),所以性能也没有什么问题。但看到rust愈来愈火热,不免好奇:如果将这个ETL程序用rust来写,能否带来性能上的提升?
为省时间,先不用rust将整个程序重写,而是针对该场景的关键环节进行模拟测试:1,clone测试文件。2,扫描目录;3,加载文件内容至内存;4,采用正则表示式进行解析。(塞db的环节先不评估)。
测试文件
测试文件大小为26.3K,单次测试时将其clone成1000份。
测试环境
CPU R7-3700U/MEM:16G / HD: NVMe M.2 1T。鲁大师跑分38万(硬件配置一般)。OS: WIN10 20H2;WSL2 Ubuntu 20.10
软件开发环境均采用当前的最新版:rust 1.47; .net:.net5; jdk: openjdk15;
关键代码
测试结果取决于测试代码,受限于个人经验,以下代码也许并非性能最佳。
|
clone files |
san dir |
load file content |
parse |
Rust |
|
|
|
|
C# |
|
|
|
|
Java |
|
|
|
|
Windows 上Rust测试结果
注:感觉rust没有想象中的快啊。所以才蹦出这样的想法:如果用c#和java来做同样的事情,表现如何呢?
Windows 上C#测试结果
Windows 上Java测试结果
结果分析
Language |
clone files (ms)--avg |
san dir (ms)--avg |
load file content (ms)--avg |
parse (ms)--avg |
Rust |
1479 |
28 |
9622 |
1162 |
C# |
1416 |
22 |
9840 |
113 |
Java |
1578 |
39 |
10555 |
548 |
- C#总体表现最好。(不确定是否与.net 5有关。最近.net 5正式版即将发布,有些性能相关的文章如下。)
- rust在clone/scan/load测试项目上,rust和C#表现相近;但rust 在parse时最慢,(有可能是由于自己对rust regex还没有真正理解;也有可能regex包的原因)。
- Java相比C#各项表现均略慢一些。
.net 5性能提升参考阅读:
Performance Improvements in .NET 5 此文中看到,.net 5 在GC/JIT/文本处理/正则表达式/异步/集合/LINQ/网络/JSon等多个方面,相比上代.net core3.1和.net fw 4.8,性能有了大幅提升。
Microsoft: .NET 5 brings you these big performance improvements
gRPC performance improvements in .NET 5 .net 5 在此文的gRPC测试中,性能超过c++和go,仅次于rust。
其他思考
1,.net 5 正则表达式的性能,相比上代产品提升5~7倍(下面的截图来自参考资料1)。不知道这是不是本次测试中C#明显胜出的因素。
2,对于.net 技术栈的产品,可以考虑升级或者迁移到.net 5。
3,依照此模拟测试的结果中rust 的性能表现,暂不考虑将ETL程序迁移到rust。
Linux 下的性能表现
上面的测试结果令我有些好奇:莫非C#/Windows是一家的缘故。换个OS呢会怎么样呢?于是利用wsl2折腾了一番(参考:win10 wsl2 rust/c#/java 开发环境搭建)。以下是测试结果。
Ubuntu上Rust测试结果
Ubuntu上C#测试结果
Ubuntu上Java测试结果
结果分析
Language |
clone files (ms)--avg win|ubuntu |
san dir (ms)--avg win|ubuntu |
load file content (ms)--avg win|ubuntu |
parse (ms)--avg win|ubuntu |
Rust |
1479 | 15745 |
28 | 711 |
9622 | 2484 |
1162 | 1127 |
C# |
1416 | 19665 |
22 | 11 |
9840 | 4039 |
113 | 121 |
Java |
1578 | 20529 |
39 | 2438 |
10555 | 7378 |
548 | 598 |
- clone 文件的时间,3个语言均大幅变长。不过,我个人感觉,此原因应该和wsl2有关。虽然wsl2实现了完整的linux内核,但此文比较 WSL 1 和 WSL 2有提到,wsl2在跨os时性能反而下降(虽然此测试并未跨os),故难免让人怀疑与此有关。
- 由于clone时间异常增加,个人认为这组测试数据的绝对值不一定可靠,相对值应还算靠谱。带给后续的启示便是,性能测试应尽量在原生OS上进行。后续有时间和资源后,再在原生ubuntu上再测试一次。
- 相比win, rust/c#/java 的写IO 性能均下降;但(load file content)读IO的性能反而上升,与之矛盾的是,scan dir也是读IO,其性能有升有降。有点纳闷。
- 单就java/C#相比而言,java 各项表现依然慢于C#。
后记:
1,后续用rust多做一些编程实践,多一些体会。在一些bench 测试中,rust的表现往往最佳或者仅次于C语言,例如近期的一篇论文:Which Programming Languages Use the Least Electricity ,此文中rust 性能仅次于C。
|
请发表评论