缓冲区与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/