【译】 Node.js v0.12的新特性 -- 性能优化

原文: https://strongloop.com/strongblog/performance-node-js-v-0-12-whats-new/

January 21, 2014/in Community, Node.js v0.12, StrongNode /by Ben Noordhuis

 

本文地址:http://www.cnblogs.com/jasonxuli/p/4536695.html

 

Node.js v0.12版本如此长的研发周期(9个月并且还在继续,目前为止最长的)使得核心团队和贡献者有足够的机会来介绍一些性能优化。本篇博客的目的是覆盖多数的主要的点。

 

writable stream支持cork模式

writable stream 现在支持“corked”模式,类似TCP_CORK 和 TCP_NOPUSH 的socket选项。

当处于corked模式时,写入stream的数据被加入队列直到该stream被uncorked。这样Node.js会合并小的写入数据,从而减少系统调用和TCP往返。

http模块已经升级,会在发送chunked模式的请求或回复时透明的使用corked模式。如果你使用strace查看输出,你会注意到系统调用里writev多了,write少了。

 

TLS性能改进:

tls模块在v0.12有了很多修改。
在v0.10里,tls模块位于net模块的上层,透明的加解密网络流数据。这种层的方式是工程师喜欢的,但导致了一些成本 -- 严格来说不必要的内存移动和V8 VM内外调用 -- 因此需要优化。

这就是为什么v0.12版本中tls模块直接使用了libuv。现在它直接接收网络流数据并解密而不需要经过中间层。

使用空秘钥的不严格的测试显示,tls比之前快了10%,同事消耗的内存也少了。(我应该说明的是,内存的减少也许部分是因为内存管理的改进。这是v0.12的另一项优化。)

(另外,如果你想知道,那么空秘钥是不会加密目标数据的秘钥,用来衡量底层和协议的成本)。

tls模块的多数改变对于终端用户应该是透明的。最显眼的一个是tls连接现在继承于tls.TLSSocket,而不是tls.CryptoStream。


Crypto的性能改进:

有几个密码算法应该比之前更快了,有时候相当快。下面是一些信息:

Node.js的密码系统使用的是OpenSSL库。OpenSSL中的算法的一些引用的实现是由C写的;也有一些为了特殊平台和架构的汇编。

v0.10版本已经使用了汇编并且做了很多扩展。另外,在CPU支持的情况下会使用AES-NI。最近三四年的多数x86 CPU都支持。

Linux系统中,如果 grep ^flags /proc/cpuinfo | grep -w aes 这个命令发现任何匹配结果,那么你的系统就支持AES-NI。注意,类似VMWare或VirtualBox的软件可能会隐藏CPU的某些能力,包含AES-NI。

开启AES-NI的预计结果是,AES128-GCM-SHA256之类的工业强度的密码现在会快于非加密的密码,例如NULL-MD5!


减少垃圾收集的张力:

多上下文重构(multi-context refactoring)的一部分效果就是,它减少了Node.js 核心里的persistent handle。

Persistent handle是指向V8堆内对象的强引用,直到引用被删除的时候才会被GC回收。(GC认为它是artificial GC root)

Node.js的persistent handle用于缓存经常使用的值,例如字符串和对象原型。然而,persistent handle需要GC做特别的后处理,因此会导致随着handle数量而线性增加的成本。

作为多上线文清理工作的一部分,相当多的persistent handle已经被去掉,或者被切换到更轻量的机制(称作’永久句柄‘ eternal handles)

实际结果是,你的程序在GC上用的时间少了,真正干活的时间多了。现在,--prof输出中,v8::internal::GlobalHandles::PostGarbageCollectionProcessing() 应该更少的显示信息。


更好的集群性能:

见上篇。

 

更快的timer,更快的setImmediate(0,更快的process.nextTick():

setTimeout()及相关函数现在使用了一个更快也更少时钟偏移的时间来源。这项优化所有平台都可用,但是早Linux平台上更进一步的从VDSO读取当前时间,因此极大的减少了gettimeofday和clock_gettime这两个系统调用的数量。

setImmediate()和process.nextTick()也有性能调整:在一般情况下的分发添加了快速路径。上述函数已经挺快了,但现在更快。

posted @ 2015-05-29 15:03  牛太黑  阅读(691)  评论(0编辑  收藏  举报