缓冲区与string速度:为什么string更快?

我有这个名为Memcached.Js的项目,它是Memcached服务器到Node.js的一个端口。

我一直在玩string和缓冲区,比较内存占用和性能。 对于内存来说,缓冲区是不错的select。

但令我惊讶的是,对于表演来说也是如此。 执行string操作比使用缓冲区更快。 这是我试过的:

// Option 1: data.toString() - amazing, but it's the best one var commandDataStr = mdata.data.toString().substr(startPos, bytes); var commandData = new Buffer(commandDataStr); // Option 2: data.slice().toString() - the same as above... What? var commandDataStr = mdata.data.slice(startPos, startPos + bytes).toString(); var commandData = new Buffer(commandDataStr); // Option 3: data.slice() - bad var commandData = mdata.data.slice(startPos, startPos + bytes); // Option 4: data.copy() - bad as well var commandData = new Buffer(bytes); mdata.data.copy(commandData, 0, startPos, startPos + bytes); 

完整的代码在这里: https : //github.com/dalssoft/memcached.js/blob/master/lib/memcached.ascii.commands.js#L72

testing代码: ruby test/from_clients/perf_test.rb

testing表明,string比缓冲区更快。 既然这不是我所期望的,我想我可能做错了什么,但是我找不到它到底是什么。

有人能帮我一下吗?

TKS!

string内置于V8中,并在VM内分配内存。 添加缓冲区不是为了使所有string操作更快,而是要表示二进制数据,其中string是unicode。

将大量数据写入套接字时,以二进制格式存储数据要比从unicode转换更有效。

所以对于常见的操作,比如concat,我并不感到惊讶,string更快。

Buffer.slice在节点上很贵。 我发现这种模式:

 buffer.slice(start, end).toString(encoding) 

比模式慢了10倍以上:

 buffer.toString(encoding, start, end) 

即使slice没有分配任何新的缓冲区,似乎也会产生很大的成本。 从粗略的看代码,我的猜测是暴露外部分配的缓冲区为v8(通过SetIndexedPropertiesToExternalArrayData)导致它必须更新其生成的代码为缓冲区对象。

一旦创build(或切片),缓冲区看起来很快。 因此,创build更大的缓冲区而不是大量的小缓冲区,并尽可能地重用,似乎是一个合理的性能策略。

更多的想法: http : //geochap.wordpress.com/2011/05/03/node-buffers/