Node.js Undocumented(2)

简介:
  Node.js Undocumented(1)
    Node.js Undocumented(2)

    写这种系列blog,是为了监督自己,不然我估计我不会有动力写完。这一节,我将介绍下Buffer这个module。js本身对文本友好,但是处理二进制数据就不是特别方便,因此node.js提供了Buffer模块来帮助你处理二进制数据,毕竟node.js的定位在网络服务端,不能只对文本协议友好。

    Buffer模块本身其实没有多少未公开的方法,重要的方法都在文档里提到了,有两个方法稍微值的提下。

     Buffer.get(idx)

    跟buffer[idx]是一样的,返回的是第idx个字节,返回的结果是数字,如果要转成字符,用String.fromCharCode(code)即可。

    Buffer.inspect()
    返回Buffer的字符串表示,每个字节用十六进制表示,当你调用console.dir的时候打印的就是这个方法返回的结果。

    Buffer真正值的一提的是它的内部实现。Buffer在node.js内部的cpp代码对应的是SlowBuffer类(src/node_buffer.cc),但是两者之间并不是一一对应。 对于创建小于8K的Buffer,其实是从一个pool里slice出来,只有大于8K的Buffer才是每次都new一个SlowBuffer。查看源码(lib/buffer.js):
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;
    }
 

    因此,我们可以修改Buffer.poolSize这个“静态”变量来改变池的大小

    Buffer.poolSize
    Buffer类创建的池大小,大于此值则每次new一个SlowBuffer,否则从池中slice返回一个Buffer,如果池剩余空间不够,则新创建一个SlowBuffer做为池。下面的例子打印这个值并修改成16K:
console.log(Buffer.poolSize);
Buffer.poolSize
= 16 * 1024 ;

   SlowBuffer类
   SlowBuffer类我们可以直接使用的,如果你不想使用Buffer类的话,SlowBuffer类有Buffer模块的所有方法实现,例子如下:
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);
   
    请注意,SlowBuffer默认不是Global的,需要require buffer模块。

    使用建议和性能测试

    Buffer的这个实现告诉我们,要使用好Buffer类还是有讲究的,每次创建小于8K的Buffer最好大小刚好能被8k整除,这样能充分利用空间;或者每次创建大于8K的Buffer,并充分重用。我们来看一个性能测试,分别循环1000万次创建16K,4096和4097大小的Buffer,看看耗时多少:
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是为了做warm up。在我机器上的输出:
    
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和创建4097大小的Buffer,只差了一个字节,耗时却相差非常大,为什么会这样?读者可以自己根据上面的介绍分析下,有兴趣的可以留言。
    另外,可以看到创建16K和创建4K大小的Buffer,差距非常小,平均每秒钟都能创建10万个以上的Buffer,这个效率已经足以满足绝大多数网络应用的需求。

文章转自庄周梦蝶  ,原文发布时间2011-06-04

目录
相关文章
|
JavaScript API
|
JavaScript API 中间件
|
2月前
|
JavaScript
Node.js【GET/POST请求、http模块、路由、创建客户端、作为中间层、文件系统模块】(二)-全面详解(学习总结---从入门到深化)
Node.js【GET/POST请求、http模块、路由、创建客户端、作为中间层、文件系统模块】(二)-全面详解(学习总结---从入门到深化)
27 0
|
2月前
|
消息中间件 Web App开发 JavaScript
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)
70 0
|
4天前
|
JavaScript 前端开发 应用服务中间件
node.js之第一天学习
node.js之第一天学习
|
1月前
|
运维 JavaScript 前端开发
发现了一款宝藏学习项目,包含了Web全栈的知识体系,JS、Vue、React知识就靠它了!
发现了一款宝藏学习项目,包含了Web全栈的知识体系,JS、Vue、React知识就靠它了!
|
1月前
|
JavaScript
Vue.js学习详细课程系列--共32节(4 / 6)
Vue.js学习详细课程系列--共32节(4 / 6)
33 0
|
1月前
|
前端开发 搜索推荐 JavaScript
编程笔记 html5&css&js 001 学习编程从网页开始
编程笔记 html5&css&js 001 学习编程从网页开始
|
2月前
|
前端开发 JavaScript
从零开始学习前端开发:HTML、CSS、JavaScript入门指南
【2月更文挑战第1天】本文将带领读者从零开始学习前端开发,介绍HTML、CSS和JavaScript的基础知识与应用,帮助读者快速入门前端开发领域。
64 1