Использование памяти, проблема SortedList vs List - PullRequest
7 голосов
/ 04 октября 2009

Я использовал SortedList () в классе, который хранит около 15-100K данных.

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

Однако в этом случае я заметил, что List () потребляет около 20% + больше памяти.

9K предметов:

  • SortedList: 105MB
  • Список: 125 МБ

15K предметов:

  • SortedList: 115MB
  • Список: 140 МБ

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

P.S. Я использую HashSet (Of String) для обеспечения проверки уникальности при использовании List (Of) для имитации SortedList.ContainsKey (), хотя я не думаю, что это может привести к таким затратам памяти. P.S. 2: Моему приложению выделено около 80 МБ базовой памяти при запуске. Таким образом, числа должны читаться как 105-80 = 25, 125-80 = 45 и т. Д.

РЕЗУЛЬТАТЫ

Спасибо за все ответы, окончательные результаты:

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

Некоторые отметки: 500 символов, 250000 вставок

Список (OF STring) (50000)

274 мс - 226 МБ

SortedList (Of String, String) (50000)

34868 мс - 230 Мб

HashSet

420 мс - 232 МБ

Словарь (OF String, Object)

486 мс - 234 МБ

Хотя, когда я изменил счет уменьшился до 25, тогда:

Hashset для 600 000 итераций 300 МБ, где List () равно 286 МБ

Также об использовании памяти Hashset: http://blog.mischel.com/2008/04/09/hashset-limitations/ Словарь (из строки, объекта) тоже был не намного лучше в моем тесте.

Ответы [ 6 ]

9 голосов
/ 04 октября 2009

Вы предварительно распределяете емкость List<T>?

Небольшой эксперимент, который я сделал:

Эта программа занимает ~ 640 МБ

List<int> list = new List<int>(0);

for (int i = 0; i < 100000000; i++)
{
    list.Add(i);
}

Эта программа занимает ~ 320 МБ

List<int> list = new List<int>(100000000);

for (int i = 0; i < 100000000; i++)
{
    list.Add(i);
}
3 голосов
/ 04 октября 2009

A List<T> с 9-килобайтными объектами будет иметь емкость от 9 до 18 тыс., Поэтому накладные расходы для этих элементов будут между 36 и 72 килобайтами (двойное в 64-битной системе).

Очевидно, что 72 КБ даже не близко к разнице в 20 МБ, которую вы видите, поэтому использование памяти самим списком не может быть причиной. Особенно учитывая, что отсортированный список также должен содержать ссылку на каждый объект, поэтому использование памяти должно быть одинаковым.

Итак, либо есть что-то еще, использующее память, либо вы не смотрите на фактическое использование памяти приложением. Если вы просматриваете диспетчер задач, вы не видите, сколько памяти используется, а только то, сколько выделено диспетчеру памяти.

2 голосов
/ 04 октября 2009

Если у вас уже есть HashSet вашей коллекции, я не уверен, зачем вам также нужен List, но если вы ищете контейнер, который гарантирует уникальность и функциональность ContainsKey (), почему бы не универсальный словарь?

Независимо от вашего решения по приведенным выше вопросам, использование чего-то вроде диспетчера задач слишком неточно, чтобы принимать решения о потреблении памяти в .NET. Если вы еще этого не сделали, скачайте пробную версию Профили памяти .NET SciTech или ANTS Profiler и запустите ваше приложение. Сделайте снимок вашего использования памяти непосредственно перед загрузкой вашего набора и сразу после сравнения. Вы можете сделать это с несколькими типами коллекций, чтобы измерить относительное использование памяти каждого с высокой точностью.

1 голос
/ 04 октября 2009

Hashsets (& hashtables) используют много памяти! Гораздо больше, чем простой список / отсортированный список

0 голосов
/ 05 октября 2009

Я бы порекомендовал посмотреть на застекленные списки (http://sites.google.com/site/glazedlists/).. Они очень быстро сортируются и отлично справляются с памятью.

0 голосов
/ 05 октября 2009

Ознакомьтесь с Power Collections от Wintellect, эквивалента .NET для коллекций типов STL. Я считаю, что тип Set должен дать вам необходимую функциональность (уникальность), но для сравнения вам нужно будет сделать тесты. Просто мои 2 цента.

...