【CSDN 编者按】作者通过简单内容分别测试Go、Node.js、Nim、Bun服务器的性能状态,一起来学习下!
原文链接:https://lemire.me/blog/2023/10/07/web-server-hello-world-benchmark-go-vs-node-js-vs-nim-vs-bun/
未经允许,禁止转载!
编写小型Web应用程序有许多流行的框架。Go和JavaScript(Node.js)是最流行的选择。据说,Netflix 选择了 Node.js,而 Uber 为了更好的性能从 Node.js 迁移到了 Go 上。还有一些不那么流行的选择,比如 Nim。
详细分析它们的性能很难。不过使用这些框架编写一个非常小的Web应用程序,能看出明显的区别吗?最小的应用程序可以作为基准参考,因为更复杂的程序通常会更慢。
我们来试试看。我需要一个相当于“hello world”的Web服务器。我不想要任何复杂的东西,一切保持简单就好。
最简单的Go服务器如下所示:
最基本的JavaScript(Node.js)服务器如下所示:
这段程序在Bun等其他运行时中可以直接运行,但为了获得Bun运行时的最佳性能,你需要编写Bun的专用代码:
Nim提供了一种方便的方法来实现同样的结果:
另一种很有趣的方法是在Node下使用uWebSockets.js:
也可以使用C++和lithium库:
我做了一次性能评测。程序跑在一台强大的IceLake架构的64核服务器上。通常,这种大型服务器的时钟频率比较低(基频2GHz,最高能到3.2GHz)。性能测试采用了一个简单的bombardier命令:
上面的并发连接数可以一直加到1000(-c 1000)。一开始时我用了autocannon,但发现不太好用。
测试结果表明,在这个小型应用程序上,Nim的表现非常好。
系统 | 每秒请求数(10连接) | 每秒请求数(1000连接) |
Nim 2.0 和 httpbeast | 315,000 +/- 18,000 | 350,000 +/- 60,000 |
GCC12 (C++) + lithium | 190,000 +/- 60,000 | 385,000 +/- 80,000 |
Go 1.19 | 95,000 +/- 30,000 | 250,000 +/- 45,000 |
Node.js 20 和uWebSockets.js | 100,000 +/- 25,000 | 100,000 +/- 35,000 |
Bun 1.04 | 80,000 +/- 15,000 | 65,000 +/- 20,000 |
Node.js 20 (JavaScript) | 45,000 +/- 7,000 | 41,000 +/- 10,000 |
Bun + fastify | 40,000 +/- 6,000 | 35,000 +/- 9,000 |
* Bun的作者Jarred Sumner在X上说,bun中的fastify还不够快,但Bun.serve()比node:http快两倍以上。
我的Web服务器的任务非常小,所以只是一种特殊情况。我也没有进行任何配置,这只是“原始”的性能。何况,这台服务器也比通常程序员们使用的服务器更强大。
这个结果有很大的干扰,所以你不应该盲从这些数字。建议你自己跑一次性能测试。
我还看了一些其他的文章,大家都认为Go更快:
Http Server Performance: NodeJS vs. Go(https://betterprogramming.pub/http-server-performance-nodejs-vs-go-397751e8d275) 一文认为Go比Node.js快34%。他们的测试更贴近实际情况,所以更真实一些。
Server-side I/O Performance: Node vs. PHP vs. Java vs. Go (https://www.toptal.com/back-end/server-side-io-performance-node-php-java-go)一文认为Go比Node.js和Java容易扩展得多,而PHP排在最后。在压力测试中,他们发现Java和Node.js平手,而Go的速度是它们的两倍。
Performance Benchmarking: Bun vs. C# vs. Go vs. Node.js vs. Python(https://www.wwt.com/blog/performance-benchmarking-bun-vs-c-vs-go-vs-nodejs-vs-python) 一文认为Bun和Go是赢家,而Node.js只有大概一半的速度。C#的性能尚可,而Python最慢。
很想看看C、Rust和Zig在这个测试中的结果。
关于C++实现,我一开始遇到了许多问题。事实证明使用Lithium非常简单。最困难的地方就是确保你的系统上装了OpenSSL和Boost。我的解决方案和其他方案同样简单。Lithium的作者非常善解人意地给出了怎样在docker容器中运行Lithium服务器。这就意味着你不需要在系统上安装库。在docker容器中运行服务器非常合理,但有性能的额外开销,所以我在测试中没有使用。
在撰写本文时,我很开心第一次编译Nim语言的软件。不得不说,Nim给我留下了很好的印象。作者声称,Nim的创意来自Python。它的确很像Python。稍后我会重新看看Nim。