String vs byte array, производительность

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

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

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

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

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

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

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

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

2 ответов


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

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


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

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

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