2011-02-04 72 views
16

我有這個項目,名爲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

試驗表明,字符串是比緩衝區更快。由於這不是我所期待的,我認爲我可能做錯了什麼,但我找不到它究竟是什麼。

任何人都可以幫助我嗎?

Tks!

+0

你能重現一個小的測試情況下,速度的行爲嗎?如果是這樣,那麼發送一個錯誤報告。 – btilly 2011-02-04 18:37:58

回答

21

字符串內置於V8,並在虛擬機內分配內存。添加緩衝區不是爲了使所有字符串操作更快,而是要表示二進制數據,其中字符串是unicode。

當大量數據寫入到一個插座,它更有效地在二進制格式的數據,VS不必從Unicode轉換。

因此,對於常見的操作,就像CONCAT,我並不感到驚訝絃樂更快。

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/