fibjs比 Nodejs 快五倍

fibjs比 Nodejs 快五倍

原文[http://baoz.me/449778]

少废话,上代码。nodejs 代码如下:

var http = require("http");
var server = http.createServer(function(request, response) {
    response.writeHead(200, {
        "Content-Type": "text/html"
    });
    response.write("Hello World!");
    response.end();
});

server.listen(8000);

测试结果:

lion$ wrk -t12 -c400 -d30s http://127.0.0.1:8000/
Running 30s test @ http://127.0.0.1:8000/
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    38.61ms    6.18ms  77.46ms    84.50 %
    Req/Sec    837.87      134.82      1.77k     81.78 %
  297965 requests in 30.00s, 44.05MB read
  Socket errors: connect 0, read 453, write 0, timeout 90
Requests/sec:    9931.42 
Transfer/sec:      1.47MB

fibjs 相似代码如下:

var http = require("http");
var svr = new http.Server(8080, function(req) {
    var rep = req.response;
    rep.addHeader({
        "Content-Type": "text/html"
    });
    rep.body.write(new Buffer("Hello World!"));
});

svr.run();

测试结果如下:

lion$ wrk -t12 -c400 -d30s http://127.0.0.1:8080/
\Running 30s test @ http://127.0.0.1:8080/
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    16.73ms   31.61ms 162.45ms    94.93 %
    Req/Sec     3.25k    822.21      5.28k     89.45 %
  1137450 requests in 30.00s, 160.54MB read
  Socket errors: connect 0, read 282, write 0, timeout 0
Requests/sec:   37916.03 
Transfer/sec:      5.35MB

可是有些代码对 fibjs 纯属多余,精简一下:

var http = require("http");
var svr = new http.Server(8080, function(req) {
    req.response.body.write(new Buffer("Hello World!"));
});

svr.run();

测试结果如下:

lion$ wrk -t12 -c400 -d30s http://127.0.0.1:8080/
Running 30s test @ http://127.0.0.1:8080/
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    24.39ms   71.85ms 343.96ms    95.11 %
    Req/Sec     3.99k     1.00k    6.67k     91.61 %
  1379337 requests in 30.00s, 161.80MB read
  Socket errors: connect 0, read 270, write 0, timeout 0
Requests/sec:   45980.00 
Transfer/sec:      5.39MB

48 回复

fibjs 比 Node.js 快五倍

原文链接: http://baoz.me/449778

引言

在高性能服务器端应用中,选择合适的框架和技术栈至关重要。本文将通过一个简单的HTTP服务器示例来对比fibjs与Node.js的性能差异。

Node.js 示例代码

首先,我们来看一段使用Node.js编写的简单HTTP服务器代码:

var http = require("http");

var server = http.createServer(function(request, response) {
    response.writeHead(200, {
        "Content-Type": "text/html"
    });
    response.write("Hello World!");
    response.end();
});

server.listen(8000);

这段代码创建了一个HTTP服务器,监听8000端口,并返回一个简单的“Hello World!”响应。接下来,我们使用wrk工具对其进行性能测试。

Node.js 性能测试

运行以下命令进行性能测试:

wrk -t12 -c400 -d30s http://127.0.0.1:8000/

测试结果如下:

Running 30s test @ http://127.0.0.1:8000/
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    38.61ms    6.18ms  77.46ms    84.50 %
    Req/Sec    837.87      134.82      1.77k     81.78 %
  297965 requests in 30.00s, 44.05MB read
  Socket errors: connect 0, read 453, write 0, timeout 90
Requests/sec:    9931.42 
Transfer/sec:      1.47MB

从结果可以看出,Node.js服务器每秒可以处理约9931个请求,传输速率为1.47MB/s。

fibjs 示例代码

接下来,我们用fibjs编写相同的HTTP服务器代码:

var http = require("http");

var svr = new http.Server(8080, function(req) {
    var rep = req.response;
    rep.addHeader({
        "Content-Type": "text/html"
    });
    rep.body.write(new Buffer("Hello World!"));
});

svr.run();

在这段代码中,我们创建了一个fibjs HTTP服务器,监听8080端口,并返回相同的“Hello World!”响应。同样地,我们使用wrk工具进行性能测试。

fibjs 性能测试

运行以下命令进行性能测试:

wrk -t12 -c400 -d30s http://127.0.0.1:8080/

测试结果如下:

Running 30s test @ http://127.0.0.1:8080/
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    24.39ms   71.85ms 343.96ms    95.11 %
    Req/Sec     3.99k     1.00k    6.67k     91.61 %
  1379337 requests in 30.00s, 161.80MB read
  Socket errors: connect 0, read 270, write 0, timeout 0
Requests/sec:   45980.00 
Transfer/sec:      5.39MB

从结果可以看出,fibjs服务器每秒可以处理约45980个请求,传输速率为5.39MB/s。

进一步优化

为了进一步简化fibjs代码,我们可以去掉不必要的步骤:

var http = require("http");

var svr = new http.Server(8080, function(req) {
    req.response.body.write(new Buffer("Hello World!"));
});

svr.run();

再次运行性能测试:

wrk -t12 -c400 -d30s http://127.0.0.1:8080/

测试结果如下:

Running 30s test @ http://127.0.0.1:8080/
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    24.39ms   71.85ms 343.96ms    95.11 %
    Req/Sec     3.99k     1.00k    6.67k     91.61 %
  1379337 requests in 30.00s, 161.80MB read
  Socket errors: connect 0, read 270, write 0, timeout 0
Requests/sec:   45980.00 
Transfer/sec:      5.39MB

结论

通过上述测试结果可以看出,fibjs相比Node.js在处理相同任务时表现出显著的性能优势。fibjs每秒处理的请求数几乎是Node.js的五倍,这表明在某些场景下,选择fibjs作为服务器端技术栈可能会带来更好的性能表现。


弱弱的挑衅,不服来战~

再不fibjs,你就软了

前排卖瓜子汽水爆米花

楼主究竟何方妖孽,胆敢来此挑衅。

高度优化的东东,可能不好用?

挑衅成功,我去了解一下

这样的测试,意义不大,node.js 平台,默认是单线程的,是内核最小化的, 优化起来也不难。 而且,node.js 默认设置,最多只开到一小半火力,还不到!!

写的一个测试用例,你们折腾去吧!

/**
 * Don't use `ab`. `ab` sends HTTP/1.0 in HTTP requests. This causes node to
 * close the connection after each request by sending a `Connection:close` in the response.
 * Adding `-k` for keep-alive to ab does not help.
 *
 * If you use `siege`, make sure to set connection = keep-alive in your .siegerc file.
 * If not, siege defaults to HTTP/1.0.
 *
 * [@author](/user/author) liveinjs
 * [@version](/user/version) 0.0.1
 */

var http = require(‘http’); http.globalAgent.maxSockets = Infinity; var numCPUs = require(‘os’).cpus().length; var cluster = require(‘cluster’);

if (cluster.isMaster) { for (var i = 0; i < numCPUs; i++) { cluster.fork(); }

cluster.on('exit', function(worker, code, signal) {
    console.log('worker ' + worker.process.pid + ' died');
});

} else {
    http.createServer(function(req, res) {
    res.end("hello world!");
}).listen(8080);

}

http://baoz.me/fibjs 试了一下,确实有点快。

又撸了撸FibJS的文档,作者最得意的应该是coroutine相比回调的简洁优雅(且不提generator),于是我去看coroutine,发现这货根本不是coroutine,而是个Fiber管理器,至于Fiber,是个更轻量线程,而且我在coroutine接口里看到了恐怖的东西:LockSemaphore,有了这俩玩意还让不让人愉快地写异步代码了…

我底层懂得少,如果讲了什么小白的话请往死里批

第一次知道fibjs,有点意思,哈哈

这个测试代码可以再幼稚点吗?

测试代码要以操作系统通信为准,包括但不限于文件io,tcp…

有时间看看,顶南京西祠胡同的响马!先赞下

居然给转这边了,统一回复一下吧。

这并不是一次严肃的对比测试,只是一时兴起测着玩的,不必认真。简单说结果吧,孢子社区已经在 fibjs 上开发了数万行代码的服务器应用,并且稳定运行一年多。

有同学看见锁就惊恐,是不对的。nodejs 在需要资源受限时同样需要锁,并且异步锁的实现令人作呕。协程的好处是你不需要对内存加锁,但是不代表你不需要对资源加锁。比如限定数据库连接数,阻止缓存重复更新,等等,很多高级场景都是需要锁来保障的。

同时,nodejs 从来就不是单线程,同样是单线程 v8 + 后台多线程,与 fibjs 相同,并且 nodejs 的 http parse 也是 c 写的。至于说 nodejs 也可以通过 addon 来提升性能,那就强词夺理了哈哈。

最后用我在 fibjs 论坛里的一段回复结束吧:

高并发不等于高性能,随着应用层逻辑的引入,会拉平甚至拉低不同平台的并发性能,越复杂的应用,对语言本身的运算速度依赖越大。

因此拿简单的 echo 来对比并发其实是没有意义的,不同语言,开发环境,最后实际上瓶颈根本都不在基础架构上,大部分应用最后每秒能响应 100 个请求便算上很好了,基础架构每秒 5000 还是 50000 对此影响很小。

所以结论是应用开发框架比并发性能是一件很蛋疼的事情,开发范式的改变带来的应用可读性,模块低耦合,容易工程化所带来的性能提升反而收益更高。

何况 fibjs 就连基础的并发性能也秒杀 nodejs 哈哈。

最大的问题是不能使用Node的包,难道又要重复造轮子

Coroutine只是一种异步处理方案而已,怎么能算抛弃异步了,况且Node又不是只有Callback,ES6又有了Generator

baoz的宣传贴?

表示fibjs还不是特别的完善吧,Google团队好像还在不断的更新哎。不过确实可以学习学习。。。

关于Callbacks , Coroutines和 Generators。看看TJ如何评论。[https://medium.com/code-adventures/callbacks-vs-coroutines-174f1fe66127]

这是国产的吗?好牛X的样子。

看了楼上各种大大的言论,吓得我都不敢说话了。

首先撸主的确很流弊哈,只不过目前最大的软肋就是生态圈抵不过——除非撸主去把 npm 的包给搞到自己的镜像然后宣称兼容。

以及——其实在 0.11 的 node 版本一下,不知道大家有没有用过 fiber 这个 C++ 的 addon。

任何以hello world做性能对比的测试,都是耍流氓。

能不能编译几个 二进制包, 拿 VS14 编译失败, VS2010 编译也失败 囧

还没有社区啊,感觉也不能应用于生产,即使真的某方面超越了,也还是观望观望。。

现在能加快人的速度而不是机器的速度的技术才是好技术。其他都是浮云. Fibjs看似挺好,先把在线文档做好再说. 先支持一下.

关注一下

jacksontian node $ ./tools/wrk/wrk http://127.0.0.1:8080/
Running 10s test @ http://127.0.0.1:8080/
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     4.19ms    7.15ms  54.22ms   93.58%
    Req/Sec     3.91k     3.82k   16.33k    81.44%
  70239 requests in 10.01s, 9.91MB read
Requests/sec:   7016.96
Transfer/sec:      0.99MB
jacksontian node $ ./tools/wrk/wrk http://127.0.0.1:8000/
Running 10s test @ http://127.0.0.1:8000/
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   840.83us  358.15us   5.87ms   85.23%
    Req/Sec     6.41k     1.21k    9.70k    64.59%
  121425 requests in 10.00s, 17.95MB read
Requests/sec:  12143.27
Transfer/sec:      1.80MB
jacksontian node $ ./tools/wrk/wrk -t12 -c400 http://127.0.0.1:8080/
Running 10s test @ http://127.0.0.1:8080/
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    18.40ms   24.78ms 131.81ms   95.24%
    Req/Sec     1.55k     0.95k    5.96k    63.82%
  169208 requests in 10.01s, 23.88MB read
  Socket errors: connect 155, read 235, write 0, timeout 653
Requests/sec:  16907.91
Transfer/sec:      2.39MB
jacksontian node $ ./tools/wrk/wrk -t12 -c400 http://127.0.0.1:8000/
Running 10s test @ http://127.0.0.1:8000/
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    24.90ms    2.52ms  46.70ms   64.25%
    Req/Sec   817.54    397.28     1.77k    70.75%
  96824 requests in 10.00s, 14.31MB read
  Socket errors: connect 155, read 61, write 0, timeout 620
Requests/sec:   9679.52
Transfer/sec:      1.43MB

以上 8000是node,8080是fibjs。看起来跟连接数有些关系。

连接数少的时候,node性能还略好些呢。

连接数多的时候,差距没有5倍那么大。

以上测试仅供参考。

fiber和callback之争,在node社区争论了老九了,理论上callback性能比需要保存现场的fiber要高,但是callback写起来比较恶心,尤其是在err处理上

不明觉厉,围观中…

不说别的,用例为什么nodejs版本和fibjs版本一个用Buffer一个用String……

说句公道话, 前端js写过好多, nodejs也玩过, ES6生成器也折腾过. 异步回调看着优美, 实际用于生产环境真的是开发代价太高. 容易出问题, 调试麻烦. 生成器特性一度让我看到希望, 但是真正折腾进去后, 完全就是一个地狱来到另外一个地狱, 写法特别恶心人. 后面发现了fibjs, 同步的思想来开发, 的确是可以提高很多的开发效率和减少错误的发生. 一些异步产生的错误是偶发性的, 先不说重现的难度, 就算你知道问题, 你要去解决这个异步执行的流程也是非常曲折.

fibjs的确是支持不足, 基本api功能还有欠缺(其实是我的使用比较特殊, 业务性的api接口比node要丰富, 起码是所有数据库模块都已经有了)

经过研究的结果就是, 把已经写好的node底层框架全部从写成fibjs实现. 现在是node+fibjs, websocket还没有第三方库支持, 暂时只能用node的socket.io

题主需要冷静一下,回答全部问题都抱着“回调恶心反胃这样的先入为主基调”,这样讨论就没意义了。 解决 “回调地狱” 是一个问题,但不能因此就说回调丑陋,我反而觉得回调是一种非常棒的体验。 都说异步反人类,其实只是反了你们惯有的编程逻辑罢了,生活中的事物大部分不都是异步的吗? 所以说异步才是真正迎合人类,迎合更多的现实场景。 以往的全同步思维才是反人类,是机器思维。 言毕,仅此而已,有点跑题,并不是讨论fibjs和node

作为一个老年新人完全不知道你们在说什么。

非常同意,异步不可能反人类,而是顺应人类思维出现的必然产物。 一个非常简单的例子就能说明人们都在异步:

比如,你要切菜,烧水,煮面,煮菜。 如果你是同步执行,那就是先切菜、再烧水、最后煮面煮菜。 如果是异步执行就是先烧水、烧水时切菜、水开了煮面、煮差不多了就加菜。 人类的思维方式一览无余。 存在既有合理之处,问题总是能解决的。

其实很简单的思维给大家讨论了那么复杂有必要吗

怎么又顶上来了,,,,fibjs再好,社区不火,终究。。。 诶

node.js 优势并不全在于并发和快,npm生态圈是很重要的一个环节。如果想要发展壮大的话,一个高质量的用户贡献模块库是比较重要的

国内主流风格是扫一眼没玩直接开喷;国外主流是玩过瘾了再开喷。强烈建议响马大叔督促加快fibjs文档cn2en的进程,技术产品很多时候先出口再进口回来内销才是真理:)

哇塞。。。。

最近发现,es7中的 async await 的写法比较好,直观,简洁

此外,我相信如果工程比较大的话,用go是合理的方案

Generator 有个很大的好处,浏览器也支持,

压栈恢复的思路我之前也想弄,需要异步的调用就挂起interpreter,等事件结束再restore。然而即使搞个雏形也挺花时间的,你能做出来真的很棒。

根据您提供的代码示例和测试结果,可以看出 fibjs 在处理高并发请求时确实比 Node.js 更快。以下是两者的对比和简要解释。

示例代码

Node.js 版本

var http = require("http");

var server = http.createServer(function(request, response) {
    response.writeHead(200, {
        "Content-Type": "text/html"
    });
    response.write("Hello World!");
    response.end();
});

server.listen(8000);

fibjs 版本

var http = require("http");

var svr = new http.Server(8080, function(req) {
    req.response.body.write(new Buffer("Hello World!"));
});

svr.run();

测试结果分析

从测试结果来看,使用 fibjs 的服务器在相同条件下能处理更多的请求:

  • Node.js:

    Requests/sec:    9931.42 
    Transfer/sec:      1.47MB
    
  • fibjs:

    Requests/sec:   45980.00 
    Transfer/sec:      5.39MB
    

解释

fibjs 是一个基于 Fibers 技术实现的 JavaScript 运行时环境,它能够更好地利用系统资源来处理并发请求。fibjs 中的异步操作是通过 Fibers(纤程)实现的,这使得它可以更高效地管理任务调度,从而提高性能。

在上述示例中,fibjs 代码简化了响应头的设置,并且直接写入缓冲区,这减少了不必要的内存分配和字符串处理,从而提升了性能。

总结

尽管 fibjs 的性能显著优于 Node.js,但在实际生产环境中,还需要考虑其他因素,例如社区支持、库的可用性以及开发者熟悉程度等。选择哪种技术取决于具体需求和应用场景。

回到顶部