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

时间:2011-02-04 18:27:56

标签: javascript node.js string performance optimization

我有一个名为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);

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

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

测试显示字符串比缓冲区更快。因为它不是我所期待的,我想我可能做错了什么,但我找不到它究竟是什么。

有人可以帮我吗?

韩国社交协会!

2 个答案:

答案 0 :(得分:24)

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

在向套接字写入大量数据时,以二进制格式提供数据效率要高得多,而不必从unicode转换。

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

答案 1 :(得分:13)

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

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

比模式慢10倍:

buffer.toString(encoding, start, end)

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

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

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