《深入浅出Node.js》Buffer

2022-04-15  本文已影响0人  我叫Aliya但是被占用了

Buffer 是一个典型的 JavaScript 与 C++结合的模块,其性能相关部分用 C++实现,非性能相关的用 js 实现。

Buffer 所占用的内存不是通过 V8 分配的,属于 V8 堆外内存。真正的内存是在 C++层面提供的,JavaScript 层面只是使用它:

常用函数

new Buffer()已被弃用

拼接 Buffer

当两个 Buffer 相加时实际上buf1 + buf2 === buf1.toString() + buf2.toString()。所以在操作流时的 data、end 事件回调,要小心操作数据,以免出现半个字符的情况导致乱码

给流指定编码可以修正此问题stream.setEncoding("utf8"),但此方法仅支持 UTF-8、Base64 和 UCS-2/UTF-16LE 这 3 种编码。

Buffer.concat方法需要把所有 buffer 先存放在一个临时变量,待拼接后再处理(V8 堆外内存,不够用的话就是另一个问题了)。

处理更多编码类型

iconv-lite 采用纯 JavaScript 实现,iconv 则通过 C++调用 libiconv 库完成。在性能方面,由于转码都是耗用 CPU,在 V8 的高性能下,少了 C++到 JavaScript 的层次转换,纯 JavaScript 的性能比 C++实现得更好。

iconv-lite 无法转换的内容如果是多字节,会输出 �;如果是单字节,则输出?

iconv 则有三级降级策略,可能设置为尝试翻译、忽略

var iconv = new Iconv("UTF-8", "ASCII//TRANSLIT//IGNORE");
iconv.convert("ça va が"); // "ca va "

性能

网络传输字符串时,会先将字符串转换为 Buffer 后再传输,所以静态内容预先转换为 Buffer 对象,可以减少 CPU 的重复使用,节省服务器资源。

文件操作时,highWaterMark 太大会浪费内存,过小可能导致系统调用次数过多。highWaterMark 越大读取速度越快。

上一篇 下一篇

猜你喜欢

热点阅读