[nodejs]Buffer vs String

3566 ワード

疑問
nodejs公式文書によると、Bufferを使ってバイトストリームを操作するのは、一般的にStringに変換するよりも効率的である.実際の状況は全部このようですか?この疑問は簡単な解析HTTP Request Headerの例によって解く.
HTTP Request Header Demo
POST /foo HTTP/1.1\r
Host: foo.example.com\r
Content-Length: 5\r
Connection:keep-alive\r
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r
Cookie:connect.sid=OY2nKGqI3obs5lYee0JKTjhf.FDtbY1Jz5Ngw5So9Jv3MUetI5ITvrIfwgCkRw%2FcXUCk\r
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
\r
q=bar
需要
HeaderのHostの値を取得します.
Bufferバージョン
var SPACE = 0x20, // ' '
    COLON = 0x3a, // 58, :
    NEWLINE = 0x0a, // 
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
\r
return 'Host header not found'; } } } return null; };
Stringバージョン
exports.parse = function parse(data) {
    var lines = data.toString('ascii').split("
"); 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
Host: foo.example.com\r
Content-Length: 5\r
Connection:keep-alive\r
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r
Cookie:connect.sid=OY2nKGqI3obs5lYee0JKTjhf.FDtbY1Jz5Ngw5So9Jv3MUetI5ITvrIfwgCkRw%2FcXUCk\r
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
\r
q=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よりずっと速いです.