资讯专栏INFORMATION COLUMN

Node JS Buffer使用理解

changfeng1050 / 1700人阅读

摘要:起初为浏览器而设计,没有读取或操作二进制数据流的机制。使用纯字符串返回给客户端使用命令来进行性能测试,发起个并发客户端使用字符串,可以达到,传输率为每秒。使用,达到,传输率为每秒。

JavaScript 起初为浏览器而设计,没有读取或操作二进制数据流的机制。Buffer类的引入,则让NodeJS拥有操作文件流或网络二进制流的能力。

Buffer基本概念

Buffer 对象的内存分配不是在V8的堆内存中,而是Node在C++层面进行内存申请,可以理解为在内存中多带带开辟了一部分空间,但是使用时分配内存则是由Node层面完成的,释放也是由Node中v8的gc机制自动控制。Buffer基本操作,这里不在赘述,官方文档很详细。

Buffer性能对比

通常,网络传输中,都需要将数据转换为Buffer。下面做一个性能对比实验。

1.使用纯字符串返回给客户端
const http = require("http");

let hello = ""
for (var i = 0; i < 10240; i++) {
  hello += "a";
}

console.log(`Hello:${hello.length}`)
// hello = Buffer.from(hello);

http.createServer((req, res) => {
  res.writeHead(200);
  res.end(hello);
}).listen(8001);

使用ab -c 200 -t 100 http://127.0.0.1:8001/命令来进行性能测试,发起200个并发客户端

使用字符串,QPS可以达到4019.70,传输率为40491.45KB每秒。

2.使用Buffer。将字符串转换为Buffer对象,再发给客户端。
const http = require("http");

let hello = ""
for (var i = 0; i < 10240; i++) {
  hello += "a";
}

console.log(`Hello:${hello.length}`)
hello = Buffer.from(hello);

http.createServer((req, res) => {
  res.writeHead(200);
  res.end(hello);
}).listen(8001);

取消Buffer转换的注释,同样使用ab -c 200 -t 100 http://127.0.0.1:8001/测试,同样发起200个并发客户端。

使用Buffer,QPS达到7130.05,传输率为71822.74KB每秒。
性能是原来的177%,极大的节省了服务器资源。
上面这个对比示例参考于《深入浅出Node JS》。

那么问题来了,为什么会有这么大的性能提升呢?

道理其实很简单,在NodeJS中,进行http传输时,若返回的类型为string,则会将string类型的参数,转换为Buffer,通过NodeJS中的Stream流,一点点的返回给客户端。如果我们直接返回Buffer类型,就没有了转换操作,直接返回,减少了CPU的重复使用率。这一部分逻辑见Node源码https://github.com/nodejs/node/blob/v10.9.0/lib/_http_outgoing.js#L612

在上面性能对比示例中,返回string时,每次请求都需要将string装换成Buffer返回;而直接返回Buffer时,这个Buffer是我们启动服务时就存放在内存中的,每次请求直接返回内存中的Buffer即可,因此Buffer使用前后QPS提升了很多。

因此,我们在写业务代码时,部分资源可以预先转换为Buffer类型(如js、css等静态资源文件),直接返回buffer给客户端,再比如一些文件转发的场景,将获取到的内容储存为Buffer直接转发,避免额外的转换操作。

参考资料:

http://nodejs.cn/api/buffer.html

https://book.douban.com/subje...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/108331.html

相关文章

  • Node.js 中的缓冲区(Buffer)究竟是什么?

    摘要:在创建时大小已经被确定且是无法调整的,在内存分配这块是由层面提供而不是具体后面会讲解。在这里不知道你是否认为这是很简单的但是上面提到的一些关键词二进制流缓冲区,这些又都是什么呢下面尝试做一些简单的介绍。 showImg(https://segmentfault.com/img/remote/1460000019894717?w=1280&h=850); 多数人都拥有自己不了解的能力和机...

    scwang90 评论0 收藏0
  • Node闲谈之Buffer

    摘要:闲谈系列不涉及具体的讲解,只会勾勾画画一些自己认为比较重要的特性。我们一般认为用两个字节位表示,并且完全囊括了字符集。将其转换成进制就是只是表示它们是码。三的读取和写入相关重要的只有能够读写,才能够显示其存在的价值。 原文地址:http://www.cnblogs.com/DeanCh... 在刚接触Nodejs的时候,有些概念总让学前端的我感到困惑(虽然大学的时候也是在搞后端,世界上...

    Godtoy 评论0 收藏0
  • Node Buffer解读

    摘要:是什么存在于全局对象上,无需引入模块即可使用,可见重要性非同一般。可以理解是在内存中开辟的一片区域,用于存放二进制数据。大小通过参数指定,默认情况下是。一般情况下位系统大约是,位系统大约是。 Buffer是什么? Buffer存在于全局对象上,无需引入模块即可使用,可见重要性非同一般。可以理解Buffer是在内存中开辟的一片区域,用于存放二进制数据。Buffer所开辟的是堆外内存。 B...

    Zack 评论0 收藏0
  • Node.js - 200 多行代码实现 Websocket 协议

    摘要:预备工作序最近正在研究相关的知识,想着如何能自己实现协议。监听事件就是协议的抽象,直接在上面监听已有的事件和事件这两个事件。表示当前数据帧为消息的最后一个数据帧,此时接收方已经收到完整的消息,可以对消息进行处理。 A、预备工作 1、序 最近正在研究 Websocket 相关的知识,想着如何能自己实现 Websocket 协议。到网上搜罗了一番资料后用 Node.js 实现该协议,倒也没...

    张巨伟 评论0 收藏0
  • 精读《深入浅出Node.js

    摘要:从社区和过往的经验而言异步编程的难题已经基本解决无论是通过事件还是通过模式或者流程控制库。本章主要介绍了主流的几种异步编程解决方案这是目前中主要使用的方案。最后因为人们总是习惯性地以线性的方式进行思考以致异步编程相对较为难以掌握。 前言 如果你想要深入学习Node,那你不能错过《深入浅出Node.js》这本书,它从不同的视角介绍了 Node 内在的特点和结构。由首章Node 介绍为索引...

    codergarden 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<