Node.js Undocumented(1)
Node.js Undocumented(2)
写这U系列blogQ是Z监督自己Q不然我估计我不?x)有动力写完。这一节,我将介绍下Bufferq个module。js本nҎ(gu)本友好,但是处理二进制数据就不是特别方便Q因此node.js提供了Buffer模块来帮助你处理二进制数据,毕竟node.js的定位在|络服务端,不能只对文本协议友好?br />
Buffer模块本n其实没有多少未公开的方法,重要的方法都在文档里提到了,有两个方法稍微值的提下?br />
Buffer.get(idx)
跟buffer[idx]是一L(fng)Q返回的是第idx个字节,q回的结果是数字Q如果要转成字符Q用String.fromCharCode(code)卛_?br />
Buffer.inspect()
q回Buffer的字W串表示Q每个字节用十六q制表示Q当你调用console.dir的时候打印的是q个Ҏ(gu)q回的结果?br />
Buffer真正值的一提的是它的内部实现。Buffer在node.js内部的cpp代码对应的是SlowBufferc(src/node_buffer.cc)Q但是两者之间ƈ不是一一对应?strong>对于创徏于8K的BufferQ其实是从一个pool里slice出来Q只有大?K的Buffer才是每次都new一个SlowBuffer。查看源码(lib/buffer.js)Q?span style="color: #000000;">
Buffer.poolSize = 8 * 1024;
if (this.length > Buffer.poolSize) {
// Big buffer, just alloc one.
this.parent = new SlowBuffer(this.length);
this.offset = 0;
} else {
// Small buffer.
if (!pool || pool.length - pool.used < this.length) allocPool();
this.parent = pool;
this.offset = pool.used;
pool.used += this.length;
}
因此Q我们可以修改Buffer.poolSizeq个“静?#8221;变量来改变池的大?br />
Buffer.poolSize
Buffercd建的池大,大于此值则每次new一个SlowBufferQ否则从池中sliceq回一个BufferQ如果池剩余I间不够Q则新创Z个SlowBuffer做ؓ(f)池。下面的例子打印q个值ƈ修改?6K:
console.log(Buffer.poolSize);
Buffer.poolSize=16*1024;
SlowBufferc?/strong>
SlowBuffercL们可以直接用的Q如果你不想使用Buffercȝ话,SlowBuffercLBuffer模块的所有方法实玎ͼ例子如下Q?br />var SlowBuffer=require('buffer').SlowBuffer
var buf=new SlowBuffer(1024)
buf.write("hello",'utf-8');
console.log(buf.toString('utf-8',0,5));
console.log(buf[0]);
var sub=buf.slice(1,3);
console.log(sub.length);
h意,SlowBuffer默认不是Global的,需要require buffer模块?br />
使用和性能试
Buffer的这个实现告诉我们,要用好Bufferc还是有讲究的,每次创徏于8K的Buffer最好大刚好能?k整除Q这栯充分利用I间Q或者每ơ创建大?K的BufferQƈ充分重用。我们来看一个性能试Q分别@?000万次创徏16K,4096?097大小的BufferQ看看耗时多少Q?br />function benchmark(size,repeats){
var total=0;
console.log("create %d size buffer for %d times",size,repeats);
console.time("times");
for(var i=0;i<repeats;i++){
total+=new Buffer(size).length;
}
console.timeEnd("times");
}
var repeats=10000000;
console.log("warm up
")
benchmark(1024,repeats);
console.log("start benchmark")
benchmark(16*1024,repeats);
benchmark(4096,repeats);
benchmark(4097,repeats);
创徏1024的Buffer是ؓ(f)了做warm up。在我机器上的输出:(x)
start benchmark
create 16384 size buffer for 10000000 times
times: 81973ms
create 4096 size buffer for 10000000 times
times: 80452ms
create 4097 size buffer for 10000000 times
times: 138364ms
创徏4096和创?097大小的BufferQ只差了一个字节,耗时却相差非常大Qؓ(f)什么会(x)q样Q读者可以自己根据上面的介绍分析下,有兴的可以留言?br /> 另外Q可以看到创?6K和创?K大小的BufferQ差距非常小Q^均每U钟都能创徏10万个以上的BufferQ这个效率已l以满绝大多数网l应用的需求?br />
]]>