缓冲区与字符串速度:为什么String更快?

Dav*_*Sb. 20 javascript string optimization performance node.js

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

我一直在玩字符串和缓冲区,比较内存占用和性能.对于内存,毫无疑问缓冲区是正确的选择.

但令我惊讶的是,表演也是如此.执行字符串操作比使用缓冲区更快.这是我试过的:

// 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);
Run Code Online (Sandbox Code Playgroud)

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

测试代码: ruby test/from_clients/perf_test.rb

测试表明字符串比Buffer更快.因为它不是我所期待的,我想我可能做错了什么,但我找不到它究竟是什么.

有人能帮我一下吗?

TKS!

clo*_*ead 27

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

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

所以对于常见的操作,比如concat,我并不感到惊讶.字符串更快.


Geo*_*ell 14

Buffer.slice在节点上很昂贵.我发现了这个模式:

buffer.slice(start, end).toString(encoding) 
Run Code Online (Sandbox Code Playgroud)

比模式慢10倍以上:

buffer.toString(encoding, start, end)
Run Code Online (Sandbox Code Playgroud)

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

一旦创建(或切片),缓冲区似乎很快.因此,创建更大的缓冲区而不是许多小缓冲区,并在可能的情况下重用似乎是一种合理的性能策略.

关于这方面的更多想法:http://geochap.wordpress.com/2011/05/03/node-buffers/