[nodejs]Buffer vs String
疑问
按nodejs官方的文档说明,使用Buffer操作字节流通常会比转化成String要高效。
实际情况全都是这样的吗?
本文通过一个简单的解析HTTP Request Header实例来解开此疑问。
HTTP Request Header Demo
POST /foo HTTP/1.1\r\n
Host: foo.example.com\r\n
Content-Length: 5\r\n
Connection:keep-alive\r\n
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n
Cookie:connect.sid=OY2nKGqI3obs5lYee0JKTjhf.FDtbY1Jz5Ngw5So9Jv3MUetI5ITvrIfwgCkRw%2FcXUCk\r\n
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.41 Safari/535.7
\r\n\r\n
q=bar
需求
获取Header中Host的值
Buffer版本
var SPACE = 0x20, // ' '
COLON = 0x3a, // 58, :
NEWLINE = 0x0a, // \n
ENTER = 0x0d; // \r
exports.parse = function parse(data) {
var line_start = 0, len = data.length;
for(var i = 0 ; i < len; i++) {
// Host: xxx.abc.com
if(data[i] === COLON) {
var key = data.toString('ascii', line_start, i).toLowerCase();
i++; // skip ':'
if(key === 'host') {
var value_start = i;
while(i < len) {
if(data[i] === ENTER) {
return data.toString('ascii', value_start, i).trim().toLowerCase();
}
i++;
}
}
} else if(data[i] === ENTER && data[i+1] === NEWLINE) {
i += 2;
line_start = i;
if(data[i] === ENTER && data[i+1] === NEWLINE) {
// \r\n\r\n
return 'Host header not found';
}
}
}
return null;
};
String版本
exports.parse = function parse(data) {
var lines = data.toString('ascii').split("\n");
var cut, name, host;
for (var i = 0, len = lines.length; i < len; i++) {
cut = lines[i].split(':');
name = cut[0];
if (name === 'Host') {
if (cut[1] === undefined) {
return 'Host header not found';
}
host = cut[1].trim().toLowerCase();
return host;
}
}
return null;
};
测试脚本
var buffer_parse = require('./string-buffer-benchmark-parse-header-buffer').parse
, string_parse = require('./string-buffer-benchmark-parse-header-string').parse;
var data = new Buffer('POST /foo HTTP/1.1\r\nHost: foo.example.com\r\nContent-Length: 5\r\nConnection:keep-alive\r\nAccept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nCookie:connect.sid=OY2nKGqI3obs5lYee0JKTjhf.FDtbY1Jz5Ngw5So9Jv3MUetI5ITvrIfwgCkRw%2FcXUCk\r\nUser-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.41 Safari/535.7\r\n\r\nq=bar');
//console.log(buffer_parse(data));
//console.log(string_parse(data), data.length);
var n = 1000000;
var start = new Date();
for(var i = 0; i < n; i++) {
buffer_parse(data);
}
console.log('buffer_parse take: ' + (new Date() - start) + ' ms');
start = new Date();
for(var i = 0; i < n; i++) {
string_parse(data);
}
console.log('string_parse take: ' + (new Date() - start) + ' ms');
测试结果
$ node string-buffer-benchmark.js
buffer_parse take: 1888 ms
string_parse take: 4948 ms
结论
Buffer比String快多了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
2010-11-19 让python的Cookie.py模块支持:冒号做key
2009-11-19 (myconnpy出现,pymysql可以入冷宫了)打个小补丁,让pymysql正确处理日期类型和NULL类型