Строка против байтового массива, Производительность - PullRequest
10 голосов
/ 24 октября 2011

(Этот пост касается высокочастотного программирования типа)

Я недавно видел на форуме (я думаю, что они обсуждали Java), что если вам нужно проанализировать много строковых данных, лучше использовать байтовый массив, чем строку с split (). Точный пост был:

Один трюк производительности для работы с любым языком, C ++, Java, C # чтобы избежать создания объекта. Это не стоимость размещения или GC, его стоимость доступа к большим массивам памяти, которые не помещаются в кэш процессора.

Современные процессоры намного быстрее, чем их память. Они останавливаются для многих, много циклов для каждого кеша. Большая часть бюджета процессора ЦП выделено для уменьшения этого с большими кешами и большим количеством тиков.

Графические процессоры решают проблему по-другому, имея множество потоков, готовых к выполнить, чтобы скрыть задержку доступа к памяти и иметь мало или нет кеша и потратить транзисторы на большее количество ядер.

Так, например, вместо использования String и split для разбора сообщение, используйте байтовые массивы, которые могут быть обновлены на месте. Вы действительно хотите чтобы избежать произвольного доступа к памяти через большие структуры данных, по крайней мере, в внутренние петли.

Он просто говорит: «Не используйте строки, потому что они являются объектами, а создание объектов обходится дорого»? Или он говорит что-то еще?

Гарантирует ли использование байтового массива данные в кеше как можно дольше? Когда вы используете строку, она слишком велика, чтобы ее можно было хранить в кэше процессора? Вообще, использование примитивных типов данных - лучший способ для написания более быстрого кода?

Ответы [ 2 ]

11 голосов
/ 24 октября 2011

Он говорит, что если вы разбиваете фрагмент текста на отдельные строковые объекты, у этих строковых объектов локальность хуже, чем у большого массива текста.Каждая строка и массив символов, которые она содержит, будут где-то в памяти;они могут быть распространены повсюду.Вполне вероятно, что кэш-память будет вынуждена входить и выходить, чтобы получить доступ к различным строкам при обработке данных.Напротив, один большой массив имеет наилучшую возможную локализацию, поскольку все данные находятся в одной области памяти, а перегрузка кеша будет сведена к минимуму.

Конечно, существуют ограничения на это:если текст очень, очень большой, и вам нужно только разобрать его часть, то эти несколько небольших строк могут поместиться в кеше лучше, чем большой кусок текста.

2 голосов
/ 24 октября 2011

Существует множество других причин использовать byte[] или char* вместо строк для HFT. Строки состоят из 16-битного char в Java и являются неизменяемыми. byte[] или ByteBuffer легко перерабатываются, имеют хорошее расположение кеша, могут быть в куче (прямое), сохраняя копию, избегая кодировщиков символов. Все это предполагает, что вы используете данные ASCII.

char* или ByteBuffers также могут быть сопоставлены с сетевыми адаптерами для сохранения другой копии. (С некоторой возни для ByteBuffers)

В HFT вы редко имеете дело с большими объемами данных одновременно. В идеале вы хотите обрабатывать данные, как только они поступают в Socket. то есть по одному пакету за раз. (около 1,5 КБ)

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