Как можно максимально эффективно хранить список строк (память)? - PullRequest
0 голосов
/ 08 февраля 2019

У меня огромный список строк.Я хочу держать эти списки как эффективные для памяти.Я пытался удержать список.Но он использует 24 байта для каждой строки, которая имеет 5 символов.А именно, должно быть несколько областей над головой.

Затем я попытался удержать строковый массив.Использование памяти было немного эффективным.Но у меня все еще есть проблема с использованием памяти.

Как мне хранить список строк?Я знаю, что «C # резервирует 2 байта для каждого символа».Я хочу держать строку, которая имеет 5 символов как 5 * 2 = 10 байтов.Но почему он использует 24 байта для этого процесса?

Спасибо за помощь.

введите описание изображения здесь

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

Во-первых, обратите внимание, что разница между List<string> , созданным в правильном размере , и string[] (того же размера) несущественна для любого нетривиального размера;List<T> на самом деле просто модная оболочка для T[] с возможностями вставки / изменения размера / и т.д.Если вам нужно только хранить данные: T[] нормально, но обычно List<T>.

Что касается строки - это не C #, который резервирует что-либо - это .NET, который определяет, чтоstring - это объект, который внутренне имеет длину (int) плюс память для данных char, 2 байта на char.Но: объекты в .NET имеют заголовки объектов, отступы / выравнивание и т. Д., И, что важно, a минимальный размер .Так что да, они занимают больше памяти, чем просто необработанные данные, которые вы пытаетесь представить.

Если вам нужны только фактические данные , вы можете хранить данные не как string, но в качестве необработанной памяти - либо просто большой byte[] или byte*, либо в виде парной пары int[] / int* (для длин и / или смещений на странице) и char[] / char* (для фактических символьных данных) или byte[] / byte*, если вы можете работать с закодированными данными (т.е. вы в основном заинтересованы в работе ввода-вывода).Однако работать с такой формой будет крайне неудобно - практически ни один из распространенных API не захочет играть с вами, если вы не говорите в string.Существуют некоторые API, которые принимают необработанные байтовые / символьные данные, но в основном это API-интерфейсы кодировщика / декодера и некоторые API-интерфейсы ввода-вывода.Итак, еще раз: если это не то, что вы делаете: это не закончится хорошо .Совсем недавно появилось несколько Span<char> / Span<byte> API, которые сделали бы это немного менее неудобным (если вы можете использовать последние сборки .NET Core и т. Д.), Но: я сильно подозреваю, что в большинствев общих случаях вам просто придется принять string накладные расходы и жить с ними.

0 голосов
/ 08 февраля 2019

Минимальный размер любого объекта в 64-битном .NET составляет 24 байта.

В 32-битном это немного меньше, но всегда есть по крайней мере 8 байтов для заголовка объекта, и здесь мы ожидаемстрока для хранения это длина (4 байта).8 + 4 + 10 = 22. Я предполагаю, что он также хочет / нуждается в том, чтобы все объекты были выровнены по 4 байта.Поэтому, если вы храните их как объекты, вы не получите намного меньшее представление.

Если это все 7-битные символы типа ASCII, вы можете хранить их как массивы байтов, но каждый массив будетвсе еще занимают некоторое место.

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

...