.NET я должен хранить ссылки или значения? - PullRequest
0 голосов
/ 10 августа 2010

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

  • Ссылки на экземпляры (они не являютсяStructs, только ref классы)
  • Хеш-код элементов
  • Имя имени свойств (строки), которые были обработаны

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

Итак, мой вопрос: что из приведенного выше массива стоит меньше памяти.

Ответы [ 2 ]

3 голосов
/ 10 августа 2010

Хранение ссылок на объект кажется самым простым и самым дешевым вариантом памяти .

Если вы используете это для проверки "было ли это обработано", лучшим вариантом (для быстрой проверки), вероятно, реализует Object.Equals и Object.GetHashCode в вашем классе, а затем использует HashSet<T>.HashSet<T> хорош для этого, потому что он предоставляет метод O (1) Contains () .

Если вы не можете изменить класс, чтобы разрешить хэширование, вы можете альтернативно реализовать IEqualityComparer для объекта.

0 голосов
/ 10 августа 2010

Хеш-коды в стиле .NET нельзя использовать, если возможный диапазон различных значений для ваших объектов не превышает 2 ^ 32, иначе вы получите ложноположительные результаты (и, учитывая парадокс дня рождения, это может происходить чаще, чемможно подумать даже с отличной хэш-функцией).Хеш-коды дают быструю ссылку на набор из нуля или более элементов, которые затем проверяются на равенство.Следовательно, решение на основе хеш-кода потребует от вас сохранения ссылки на каждый объект в любом случае, и, следовательно, не может быть меньше в памяти для хранения только ссылок.

Если объекты не могут быть собраны сборщиком мусора(т.е. они все еще «живы» для другой части приложения), тогда стоимость хранения ссылки будет 4 или 8 байтов в зависимости от архитектуры.Если бы они могли быть GC'd, тогда стоимость зависит от размера графа этого объекта.

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

public class ObjectOfInterest
{// all fields public for sake of simplicity in example
    public int ID; // this is important diff id - diff object.
    public int ParID; // this is unimportant, as same for all objects processed here.
    public ParentType Parent; // this is just memoised based on _parID;
    public decimal Val; // this is important.
    public string Name; // unimportant for our purposes.
    public RelatedType Stuff; // memoised based on _id
}

Затем мы можем создать связанное:

public struct HashObject
{
    private readonly int _id;
    private readonly decimal _val;
    public HashObject(ObjectOfInterest ooi)
    {
        _id = ooi.ID;
        _val = ooi.Val;
    }
    public bool Matches(ObjectOfInterest ooi)
    {
        return _id == ooi.ID && _val == ooi.Val;
    }
    // because one of the options as to how to store *this* is hashing
    public bool Equals(HashObject ho)
    {
        return _id == ho._id && _val == ooi._val;
    }
    public override bool Equals(object obj)
    {
        return Equals(obj as HashObject);
    }
    public int GetHashCode()
    {
        unchecked
        {
            return _val.GetHashCode() ^ (_id << 16) ^ (_id >> 16);
        }
    }
}

Теперь мы сохраняем объекты HashObject и используем их, чтобы отметить, что мы сделали.В этом случае мы собираемся занять как минимум 20 байтов для хранения этой структуры, плюс накладные расходы на любые средства, которые мы должны сохранить.Меньше, если ObjectOfInterest теперь может быть GC'd, бессмысленно, если они все еще находятся в памяти.

Существует подход хэша и равенства (знание вероятных значений может улучшить насколько хорош хеш), если вы решили сохранитьони сами в HashSet.HashSet не будет самой эффективной коллекцией памяти, хотя, возможно, с учетом дополнительной нагрузки, которую вы вкладываете во все эти сравнения, вам нужен более быстрый поиск.Это область для экспериментов над теорией (особенно потому, что детали меняются в зависимости от ваших объектов).Если вы можете принять во внимание сложность поиска по времени при постоянном сканировании массивов, то это ваш лучший выбор.

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

...