Который занимает меньше места, UInt64 или строка в C # - PullRequest
0 голосов
/ 03 марта 2012

Что будет лучшей идеей в контексте C #,

  1. В C # я использую словарь.Я хочу, чтобы он занимал меньше места в памяти.что будет лучше?

    Словарь, в котором тип ключа Uint64 или тип ключа string?в обоих случаях значением является пользовательский класс, который одинаков для каждого словаря.

    Я объявил словарь следующим образом,

    private static readonly Dictionary<string, List<Node>> HashTable =
        new Dictionary<string, List<Node>>();
    

    узел класса определен, как показано ниже,

    public class Node
    {
        public UInt64 CurrentIndex { get; set; }
        public string NextHashedString { get; set; }
        public int NextHashPos { get; set; }
    }
    

    Ключ строки на самом деле является хеш-значением из строки, вычисленной следующим образом. Длина строки может быть от 1 до 20 символов.

    static UInt64 CalculateHash(string read, bool lowTolerance)
    {
        UInt64 hashedValue = 0;
        int i = 0;
        while (i < read.Length)
        {
            hashedValue += read.ElementAt(i) * (UInt64)Math.Pow(31, i);
            if (lowTolerance) i += 2;
            else i++;
        }
        return hashedValue;
    }
    

    Теперь я хочу сохранить этот хешзначение в качестве ключа к словарю.Какая будет лучшая идея.Я использую как Uint64 или я конвертирую его в строку и использую строку как ключ словаря.Моя основная цель - чтобы словарь использовал минимальное пространство и время поиска ключа было быстрее.

  2. У меня есть файл с 3571079 символами.Могу ли я прочитать весь файл в строку или мне нужны расширенные структуры данных?

1 Ответ

3 голосов
/ 03 марта 2012

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

Есть толькоЯ могу вспомнить одну ситуацию, когда ключ UInt64 может вызывать более высокое использование памяти, чем строка: если процесс 32-битный (x86), ссылки 32-битные.Если словарь большой, но почти пустой, будет много пустых Dictionary<K,V>.Entry экземпляров.Для ключей UInt64 ключевая часть этих экземпляров будет 64-битной (даже если явное значение не назначено), а для строковых ключей - только 32-битная.Таким образом, общий объем выделенной памяти будет больше для словаря с ключами UInt64.Но это очень теоретическая ситуация.

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

Если вы просто получили бы строковый ключ, вызвав ToString для значения UInt64, вы должны сначала перейти на версию UInt64.Это будет более эффективным во всех отношениях.

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

...