2016-10-31 4 views
0

Ситуация:C# строка размер в рабочей памяти

На 64x .NET сборки хранить около 50 миллионов строки в HashSet и моя RAM идет от 1.5Gb до 7.5Gb.

2 Вопросы:

Глядя на 6 Гб (7.5-1.5) RAM принятых строк ... Я правильно, если я заявляю, что:

  1. объект HashSet size = 8 bytes * количество строк ..., а остальные до 6GB - фактические строки, сохраненные в ОЗУ?

  2. Если да, если я бы сохранить его в БД и использовать Hibernate для примера (с той же RAM) я хранить больше строк в объекте HashSet , но мне нужно будет принять во учетной записи Накладные расходы R/W DB?

+0

Не должно быть 64 бит = 8 байтов на элемент в Hashset? –

+0

true, моя ошибка – doremifasolasido

+0

Что означает «моя RAM»? Частный рабочий набор? – Luaan

ответ

1

Не совсем. Есть немного больше для ведения журнала объекта, чем размер указателя. Заголовок объекта находится где-то между 12-24 байтами (я не уверен, что это на 64-битном - он определен, но у меня нет времени для поиска точного значения прямо сейчас :)). Длина строки составляет еще 4-8 байт. Еще 4 байта для кэшированного хэша. Каждый символ не менее два байта. Учитывая, что из 50 миллионов объектов вы получаете размер памяти 6 ГБ, вы получаете в среднем около 128 байт на объект. Это означает, что между 46-54 символами на строку (включая двухбайтовый нулевой ограничитель). И я, скорее всего, забываю и другие источники накладных расходов.

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

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

Что касается других решений, если вам нужны материалы в памяти, вам не хватает места. Возможно, если ваши данные все в ASCII, вы можете избежать использования Unicode. Если ваши строки не очень короткие, это действительно единственное, что может сделать заметную разницу. Но мы действительно не можем сказать - мы не знаем, из чего сделаны ваши данные. Возможно, сжатые строки в памяти будут работать отлично? Мы не можем знать - вам нужно проверить это самостоятельно.

EDIT:

Поскольку данные, которые вы хотите сохранить только несколько цифр, string это бесполезная трата памяти и производительности в целом. Вы можете делать все без косвенных указаний и использовать только типы значений.

Теперь, если вы знакомы с небезопасного кода, фиксированные буферы могут сделать это очень простой и легкий в использовании:

public unsafe struct SevenNumbers 
{ 
    public fixed ushort Numbers[7]; 
} 

(не забудьте добавить GetHashCode и Equals переопределение)

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

Небезопасный код обычно используется для таких оптимизаций, но если вы не знакомы/небезопасны с небезопасным кодом, вы можете сделать то же самое с немного большим количеством кода. Либо вы будете иметь доступ к номерам в виде отдельных полей (Number1, Number2, ...), или вы должны будете использовать пользовательский индексатор притворяться отдельные поля действительно массив:

public ushort this[int index] 
{ 
    get 
    { 
    if (index < 0 || index > 7) throw new IndexOutOfRangeException(); 

    switch (index) 
    { 
     case 0: return Number1; 
     case 1: return Number2; 
     ... 
    } 
    } 
} 

В в обоих случаях ваши ~ 100 байт строки получили всего 14 байтов - неплохо :) Если вы хотите нажать эту кнопку дальше, вы можете немного упаковать бит и превратить это еще ниже в 10 байт (так как вы требуется не более 11 бит для каждого номера), но это, скорее всего, перебор, а код для обработки бит-бит намного сложнее (и подвержен ошибкам :)).

+0

Пример строки: 900.900.900.900.900.1000.1900. Только цифры и точка (я могу заменить точку чем угодно). Любая идея (на вершине головы), которая может уменьшить размер в моем случае? Или соответствующее направление исследований будет отличным – doremifasolasido

+0

@LaRage Как долго могут быть цифры? Если вы можете сделать их целыми числами постоянной длины, вы можете значительно увеличить объем памяти, сохраняя при этом поиск простым и быстрым. – Luaan

+0

7 номеров между 700 и 1900 – doremifasolasido