开发者

Buffer vs String speed: Why is String faster?

开发者 https://www.devze.com 2023-02-08 09:28 出处:网络
I have this project, called Memcached.Js, which is a port of Memcached server to Node.js. I\'ve been playing arround with strings and buffers, comparing memory footprint and performance. For memory,

I have this project, called Memcached.Js, which is a port of Memcached server to Node.js.

I've been playing arround with strings and buffers, comparing memory footprint and performance. For memory, there's no question that buffer is the right choice.

But for my surprise the same is not true for performace. Performing string manipulation is faster than using buffer. This is what I tried:

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

The complete code is here: https://github.com/dalssoft/memcached.js/blob/master/lib/memcached.ascii.commands.js#L72

Testing the code: ruby test/from_clients/perf_test.rb

The tests showed that Strings are faster than Buffer. Since it's not what I was expecting, I think I'm probably doing something wrong, but 开发者_运维问答I can't find exactly what it is.

Can anyone help me here?

Tks!


Strings are built-in to V8, and allocate memory within the VM. Buffers were added not to make all string operations faster, but to represent binary data, where as Strings are unicode.

When writing large amounts of data to a socket, it's much more efficient to have that data in binary format, vs having to convert from unicode.

So for common operations, like concat, I'm not surprised Strings are faster.


Buffer.slice is expensive in node. I've found that the pattern:

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

was more than 10 times slower than the pattern:

buffer.toString(encoding, start, end)

Even though slice doesn't allocate any new buffer, it seems to incur a significant cost. From a cursory look at the code, my guess is that exposing the externally allocated buffer to v8 (via SetIndexedPropertiesToExternalArrayData) causes it to have to update its generated code for the buffer object.

Once created (or sliced), buffers seem fast. So creating bigger buffers instead of lots of little ones, and reusing when possible seems like a reasonable strategy for performance.

More thoughts on this: http://geochap.wordpress.com/2011/05/03/node-buffers/

0

精彩评论

暂无评论...
验证码 换一张
取 消