Где хранятся типы значений в (C #) общих коллекциях

Это правда, что универсальные коллекции работают лучше, чем неуниверсальные коллекции для типов значений. (т.е. список против ArrayList).

Но почему это, кроме шага по бокс-распаковке? Где хранятся объекты типа значения после добавления в коллекцию? В неуниверсальных коллекциях они будут упакованы и сохранены в куче, что отличается в генериках?

 Julien Roncaglia24 сент. 2010 г., 21:57
Для того же числа целых чисел sizeof (List <int>) ~ = sizeof (int []) ~ = 1/2 sizeof (ArrayList на x86) ~ = 1/3 sizeof (ArrayList на x86-64). Кроме того, локальность данных отстой на ArrayList из-за упаковки и приводит к фрагментации памяти выше, чем необходимо.

Ответы на вопрос(5)

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

Общий список типов значений - это локальный массив этих типов значений.

Есть две области памяти, которые большинство ссылок называют «Стек» и «Куча». Большинство людей, которые используют эти термины, понятия не имеют, почему. («The Stack» может быть стеком, но The Heap почти наверняка не куча). Я предпочитаю термины «Здесь» и «Там». В штучной упаковке данные типа значения сохраняются «Там». При хранении в массиве (возможно, в общем списке) данные типа значения сохраняются «здесь». «Здесь» лучше.

 Dirk Vollmar24 сент. 2010 г., 21:57
"Здесь" - "там" ??? Какие???? А что такое "локальный массив"? Этот ответ сбивает с толку больше всего на свете.
 Dr. Wily's Apprentice24 сент. 2010 г., 23:26
Да. Я думал, что ответ был довольно ясен. Я думаю, что этот последний комментарий демонстрирует, почему вводить в заблуждение термины «Куча» и «Стек» непонятно. В самом деле, массив будет размещен в «куче», но реальный вопрос заключается в том, где выделена память для хранения каждого элемента массива? ВList<T>память для хранения типов значений находится в памяти, выделенной для массива System.Array (т. е. «здесь»). В ArrayList каждый элемент является просто ссылкой на тип значения в штучной упаковке, поэтому фактическая память для хранения каждого типа значения находится где-то в «Кучи», то есть где-то «Вне».
 Dirk Vollmar24 сент. 2010 г., 22:07
Хорошо, тогда ваше утверждение неверно (если вы имеете в виду стек в общеупотребительном смысле). И то и другоеArrayList а такжеList<T> используйте System.Array в качестве внутреннего хранилища, которое является ссылочным типом и хранится «там».
 James Curran24 сент. 2010 г., 22:02
@ 0xA3: Локальный массив - это тот, который хранится в «Стеке». Разве это более поучительно?

что основное хранилище дляList<T> я сидела[]. Так что дляList<int> значения будут сохранены в int []. Целые числа хранятся в непрерывном фрагменте памяти, выделенном из кучи собранной мусора.

То, что делает его таким быстрым, заключается не только в том, что целые числа не упакованы, а в том, что int [] очень хорошо работает с кэшем ЦП. Когда вы читаете первый элемент, вы, по сути, получаете следующие 15 бесплатно, без необходимости читать медленную оперативную память или вторичный кеш. Это работает не очень хорошо для упакованного int, потому что оно настолько велико и дополнительная ссылка может иметь плохую локальность кэша. Тем не менее, сборщик мусора действительно помогает избавиться от этой стоимости за счет сжатия кучи.

 Hans Passant24 сент. 2010 г., 23:34
@ Джим, я думаю, что ты прав, пост исправлен, чтобы указать на дополнительную стоимость разыменования.
 Jim Mischel24 сент. 2010 г., 23:09
Так чтоArrayList имеет двойной удар по производительности. Сначала вы должны разыменовать значение из массива, чтобы получить объект (тип значения в штучной упаковке), а затем вы должны распаковать его.
 Jim Mischel24 сент. 2010 г., 23:25
Но если бэк-магазин дляArrayList являетсяobject[], затем сначала вы должны найти элемент в массиве, который дает вам ссылку на объект, который содержит int. Вы должны разыменовать это, чтобы получить объект, затем вы должны распаковать его. Сравните это сListгде все, что вам нужно сделать, это взять предмет изint[] бэк-магазин.
 Allon Guralnek24 сент. 2010 г., 22:29
Ах, единственный ответ, который прямо говорит, чтоList<T> на самом деле использует массив в качестве резервного хранилища (и хорошо поставлено тоже).List<T> это просто оболочка для массива, которая добавляет поддержку изменения размера, и фактически почти все типы коллекций сводятся к массивам, за исключением специальных коллекций, таких какLinkedList<T>.

как правило, только в отношении типов значений, используемых с обобщенными элементами, по сравнению с типами значений, хранящимися в неуниверсальных эквивалентах.

Это связано с тем, что с обобщенными типами значений нет необходимости приводить их к объекту и хранить в куче (в штучной упаковке). Фактически они могут оставаться в стеке, что является более производительным.

http://msdn.microsoft.com/en-us/library/ms172181.aspx

помимо упаковки и распаковки, в том числе кэширование памяти и способ, которым они перечисляются для выполнения своей работы. Проверять, выписыватьсяэтот пост, особенно комментарии.

List<T>они все еще хранятся в куче. Разница в том, что внутриList<int> создает один массив целых чисел и может хранить числа напрямую. С ArrayList вы в конечном итоге сохраняете массив ссылок на целочисленные значения в штучной упаковке.

Ваш ответ на вопрос