Скорость буфера против строки: почему строка быстрее? - PullRequest
18 голосов
/ 04 февраля 2011

У меня есть этот проект, который называется 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!

Ответы [ 2 ]

24 голосов
/ 04 февраля 2011

Строки встроены в V8 и выделяют память внутри ВМ. Добавлены буферы не для ускорения всех строковых операций, а для представления двоичных данных, где в качестве строковых значений используется Unicode.

При записи больших объемов данных в сокет гораздо эффективнее иметь эти данные в двоичном формате, чем при преобразовании из unicode.

Так что для обычных операций, таких как concat, я не удивлен, что строки работают быстрее.

13 голосов
/ 08 мая 2011

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/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...