【问题标题】:Buffer vs String speed: Why is String faster?缓冲区与字符串速度:为什么字符串更快?
【发布时间】:2011-06-21 13:20:15
【问题描述】:

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

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

但令我惊讶的是,性能却并非如此。执行字符串操作比使用缓冲区更快。这是我尝试过的:

// 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

测试表明字符串比缓冲区快。由于这不是我所期望的,我想我可能做错了什么,但我无法确切地找到它是什么。

有人可以帮我吗?

谢谢!

【问题讨论】:

标签: javascript node.js string performance optimization


【解决方案1】:

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

将大量数据写入套接字时,以二进制格式保存数据比从 unicode 转换要高效得多。

所以对于像 concat 这样的常见操作,我并不奇怪字符串更快。

【讨论】:

    【解决方案2】:

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

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

    比模式慢 10 倍以上:

    buffer.toString(encoding, start, end)
    

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

    一旦创建(或切片)缓冲区,缓冲区似乎很快。因此,创建更大的缓冲区而不是大量的小缓冲区,并尽可能重复使用似乎是一种合理的性能策略。

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

    【讨论】:

      猜你喜欢
      • 2013-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-22
      • 2010-11-25
      • 2017-12-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多