|
Generic List of structs
|
|||
---|---|---|---|
#18+
Проясните один моментик пожалуйста. Якобы структуры помещаемые в Generic List не боксируются. В связи с чем не понятно два момента 1. Сам List<T> класс. И значит находится в куче, но он хранит ссылки на структуры, т.е. мы имеем в куче список с указателями по факту, а сами структуры в стеке ? Не помню можно ли иметь указатели на переменные в стеке, но вроде нет - там оперируют смещением от начала фрейма стека. Соответственно хочу понять как это устроена. 2. Если метод описан как List<MyStruct> MyFunc () То как происходит возврат структур из стека этого метода проястните пожалуйста. Насколько я знаю по теории, при выходе из метода со стека просто снимается весь фрейм с переменными этого метод. Но ведь мы сохраняем структуры, как они выживают, происходит некоторое неявное копирование ? В книгах данный момент не проясняется вроде. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 12:17 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
В основе List<T> - массив. Массив лежит в куче. ЕМНИП структуры отличаются от классов только тем что могут лежать как в стеке так и в куче. Объекты только в куче. У Рихтера хорошо расписано. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 12:39 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
Dima TЕМНИП структуры отличаются от классов только тем что могут лежать как в стеке так и в куче. Поправлю пока помидорами не закидали :) ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 12:41 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
Dima T, Хотите сказать, что рекламная фраза "generic list для value type хороши именно тем, что не боксируют эти value type" ложь ? Все эти годы нам врали и утверждали, что именно для этого и был создан generic List ? :) Я знаю, что List внутри себя хранит массив. Мне не ясно, где это "внутри себя" находится, если классы хранятся в куче - они и массив хранят там же ? Как выживают value type хранящиеся в этих массивах при выходе из метода. Возможно происходит неявный боксинг при выходе. но не припоминаю, чтобы хоть в одной книге конкретно об этом моменте было написано. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 12:47 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
ProBiotekно он хранит ссылки на структуры Перечтайте внимательно еще раз то, что написали. Ссылки. На структуры. ОМГ. List<T>, где T - value type, хранит копии значений. С этим связаны известные грабли хранения в листе мутабельных структур: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.
- угадайте, что будет в консольном выводе. А сами значения структур, хранящихся в коллекции, вполне себе находятся в куче. Утверждение "объекты хранятся в куче, а структуры - на стеке" справедливо только для локальных переменных, в общем случае оно неверно. Подробности см. здесь . ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 12:58 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
Вот исходник List<T> . Обычный класс. Вот хранилище Код: c# 1.
ИМХУ в рамках этой темы дальше можно забыть про List<T> и рассуждать об особенностях хранения массива. ХЗ как оно реально реализовано. Не вникал. Возможно без боксинга. Как вариант можно написать демо-пример и посмотреть IL-код на предмет боксинга. По теме боксинга у меня у самого есть вопрос: в чем его суть, для чего эта операция нужна? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:01 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
Dima TПо теме боксинга у меня у самого есть вопрос: в чем его суть, для чего эта операция нужна? Размер стека ограничен. Но обращение с ним происходит намного быстрее чем обращение к куче (поиск по указателю). Поэтому простые типы + структуры + указатель на string хранятся на стеке. Чтобы программа быстрее работала. Ну а reference type считаются большими, заполонят весь стек и программа упадет с ошибкой заполнения стека. Чтобы не было такого риска они хранятся в куче а в стеке остается указатель на этот объект. Есть момент - структуры тоже могу быть очень большими. Нужно стремится делать их маленькими, чтобы не исчерпать стек. Или переводить их в класс, если растут и угрожают стеку. Просто помнить об этой особенности. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:11 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
До, гм, кучи: https://blogs.msdn.microsoft.com/ericlippert/2010/09/30/the-truth-about-value-types/ It is frequently the case that array elements, fields of reference types, locals in an iterator block and closed-over locals of a lambda or anonymous method must live longer than the activation period of the method that first required the use of their storage. And even in the rare cases where their lifetimes are shorter than that of the activation of the method, it is difficult or impossible to write a compiler that knows that. Therefore we must be conservative: all of these storage locations go on the heap. Боксинг значимых элементов массива не нужен потому, что боксинг вообще нужен для доступа к значимой переменной, лежащей в куче - но в случае массива мы можем получить доступ к этой переменной через ссылку на сам массив+индекс элемента. Поэтому боксинг в данном случае и не делается. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:15 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
Сон Веры Павловны, Вроде бы Generic List пропагандируется как не боксирующий value type. Мол в этом его преимущество (кроме типобезопасности). А вы говорите, что он банально боксируется. Мне вот стало не понятно поэтому и задал вопрос. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:16 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
ProBiotekуказатель на string хранятся на стеке Указатель в кучу на любую локальную переменную ссылочного типа хранится на стеке. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:17 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
ProBiotekА вы говорите, что он банально боксируется. Приведите цитату, где я это говорю. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:18 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
ProBiotek, автор Сам List<T> класс. И значит находится в куче, но он хранит ссылки на структуры вы откуда тут взялись? с явы что ли мигрировали, там да если List<int> получишь з. на воротник, ( они говорят у нас боксируется - но боксируется очень быстро ( с пафосом так)) ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:22 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
ProBiotekРазмер стека ограничен. Но обращение с ним происходит намного быстрее чем обращение к куче поиск по указателю поиска нет - есть обращение по адресу. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:23 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
Сон Веры ПавловныУказатель в кучу на любую локальную переменную ссылочного типа хранится на стеке. Я просто подчеркнул особенность строки. Мало кто пишет о том, что string это reference type по сути. Только еще и не изменяемый. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:23 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
ProBiotekDima T, Хотите сказать, что рекламная фраза "generic list для value type хороши именно тем, что не боксируют эти value type" ложь ? Все эти годы нам врали и утверждали, что именно для этого и был создан generic List ? :) Я знаю, что List внутри себя хранит массив. Мне не ясно, где это "внутри себя" находится, если классы хранятся в куче - они и массив хранят там же ? Как выживают value type хранящиеся в этих массивах при выходе из метода. Возможно происходит неявный боксинг при выходе. но не припоминаю, чтобы хоть в одной книге конкретно об этом моменте было написано. Ой ЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁ!!!!!!!!!!!!!!!! 1. Нафига придумали структуры и классы? Вообще говоря размер класса нельзя/не так просто определить в момент компиляции, а размер структуры можно! Это значит что выделением памяти для классов управляет GC, а для структур.... Компилятор! Что на порядки быстрее! 2. Массив объектов хранит ссылки на объекты, массив структур - сами структуры и все это в куче. 3. Ну и если структура поле класса - она тоже лежит в куче. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:24 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
Сон Веры ПавловныПриведите цитату, где я это говорю. Сон Веры ПавловныList<T>, где T - value type, хранит копии значений. ... А сами значения структур, хранящихся в коллекции, вполне себе находятся в куче. Если я не верно воспринял эти фразы как боксинг, то это моя ошибка. Ок не буду спорить. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:27 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
ЕвгенийВВообще говоря размер класса нельзя/не так просто определить в момент компиляции откуда этот бред? дальше даже читать неинтересно ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:32 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
ProBiotek, почитай Рихтера, он много букав написал по этому поводу. Сам никак не соберусь перечитать, т.к. многое не допонял в этом вопросе, когда читал. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:32 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
В общем. Если ответ на мой вопрос "generic List со всем своим содержимым из Value type хранится в куче" - то тему можно закрывать. Мне только это и было не понятно. Я почему то верил в то, что Generic List создан именно для того, чтобы избежать боксинга. Кажется это достаточно распространенный факт - но получается ложный. Не зная этого я и начал фантазировать на тему того, как из кучи можно держать ссылки на структуры в стеке. Вот и все. Сон Веры ПавловныПеречтайте внимательно еще раз то, что написали. Ссылки. На структуры. ОМГ. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:32 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
ProBiotek, вы чтой-то не догоняете в терминологии... про боксинг-унбоксинг... ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:38 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
buserProBiotek, вы чтой-то не догоняете в терминологии... про боксинг-унбоксинг... ++ ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:38 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
ProBiotek, ну и что такое ссылка/указатель похду тож... ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:39 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
ProBiotek, боксинг подразумевает возврат ссылки на каждое конкретное боксируемое значение, и дальнейшую работу с этим значением через полученную ссылку аналогично работе со ссылочными типами. В случае массива, как я писал выше, доступ к значениям осуществляется через ссылку на сам массив+индекс в массиве, на каждый отдельный элемент массива ссылка не нужна, поэтому никакого боксинга нет, несмотря на расположение самих элементов в куче. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:40 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
в принципе можно освежить память struct A{}; A* array= (A *) malloc(sizeof(A) * 2) A** array_ref= (A **) malloc(sizeof(A*) * 2); ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:41 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
Сон Веры ПавловныProBiotek, боксинг подразумевает возврат ссылки на каждое конкретное боксируемое значение, и дальнейшую работу с этим значением через полученную ссылку аналогично работе со ссылочными типами. В случае массива, как я писал выше, доступ к значениям осуществляется через ссылку на сам массив+индекс в массиве, на каждый отдельный элемент массива ссылка не нужна, поэтому никакого боксинга нет, несмотря на расположение самих элементов в куче. Разве тот факт, что массив оказался в куче не является самим понятием боксинга? Я понимаю, что ссылку нужно хранить только на сам массив а не на каждый его элемент. Но что-то вы прям совсем путаете говоря, что "нахождение массива в куче не является боксингом". По моему это и есть именно что боксинг и тогда становится понятно как устроена функция List<MyStruct> MyFunc () ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:46 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
Для меня боксинг это когда value type оказывается в куче. Вот и все ) По моему вполне простое описание, по моему оно верное. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:47 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
Где-то в степив принципе можно освежить память struct A{}; A* array= (A *) malloc(sizeof(A) * 2) A** array_ref= (A **) malloc(sizeof(A*) * 2); Не понимаю в чем тут подвох. Ну указатель на массив. Ну указатель на указатель. На С++ никогда не писал особо, теорию знаю но всякие такие тонкости уже нет. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:51 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
ProBiotek, да это не для вас. для вас вот это https://msdn.microsoft.com/ru-ru/library/yz2be5wk.aspx ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:54 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
ProBiotekПо моему вполне простое описание, по моему оно верное. увы - ошибочное ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:58 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
Где-то в степи, В статье ничего не сказано про вложенность. Из статьи не ясно что происходит с массивом value type внутри структуры. От того и вопросы. Поэтому и есть у меня этот пробел видимо. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 13:59 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
ProBiotek, ))))) за сим откланяюсь.. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 14:01 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
Где-то в степиProBiotek, да это не для вас. для вас вот это https://msdn.microsoft.com/ru-ru/library/yz2be5wk.aspx Почитал и похоже понял ответ на вопрос ProBiotekХотите сказать, что рекламная фраза "generic list для value type хороши именно тем, что не боксируют эти value type" ложь ? "не боксируют" не синоним "размещают на стэке". В куче размещается массив, но элементы массива не требуют упаковки, поэтому данное утверждение верно. Если правильно понял, то основные тормоза при упаковке (нездоровый запутывающий термин), которая сводится к выделению места в куче и копированию туда. Распаковка проще, просто копирование обратно в стэк. Но в случае с массивом - в куче создается объект массив, а под его элементы никаких доп. выделений памяти не нужно. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 14:07 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
ProBiotekДля меня боксинг это когда value type оказывается в куче. Вот и все ) По моему вполне простое описание, по моему оно верное. Кое-кто считает иначе: J. Richter CLR via C# Chapter 5 Primitive, Reference, And Value Types It’s possible to convert a value type to a reference type by using a mechanism called boxing. Internally, here’s what happens when an instance of a value type is boxed: 1. Memory is allocated from the managed heap. The amount of memory allocated is the size required by the value type’s fields plus the two additional overhead members (the type object pointer and the sync block index) required by all objects on the managed heap. 2. The value type’s fields are copied to the newly allocated heap memory. 3. The address of the object is returned. This address is now a reference to an object; the value type is now a reference type. - не доводилось читать? Или вот: Boxing is an implicit conversion of a value type to the type object or to any interface type implemented by this value type. - https://msdn.microsoft.com/en-us/library/yz2be5wk.aspx Всё вышеописанное несколько больше, чем просто хранение неких значений в куче. Ну, и наконец: Код: c# 1. 2. 3. 4. 5. 6. 7. 8.
компилируется вот в такой IL-код: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
а Код: c# 1. 2. 3. 4. 5. 6. 7. 8.
вот в такой: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
В первом случае имеет место быть боксинг - имеется инструкция box + инструкция stelem.ref (сохранение в массиве ссылки из стека). Во втором случае нет боксинга - соответственно, нет инструкции box, и вместо stelem.ref имеем stelem.i4 (сохранение в массиве int32-значения из стека). ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 14:09 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
Ок. Спасибо. По разбираюсь еще. Я для себя боксинг осознал так, вот и все. Жизнь не портит сильно, т.к. сверх оптимизацией микросекунд заниматься не приходится и структуры вообще не практикую особо. Как говорят ASP.NET Life Cycle настолько длительный что на его фоне все эти оптимизации с боксингом погоды никак не делают. Век живи, век задавай вопросы ! ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 14:17 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
Dima T, верно, давай представим (массив структур, у стр. есть первое поле int a, второе int b) нужно прочитать у пятого элемента поле b go ... уходим по адресной арифметике от начала массива в право на пять, берем указатель делаем смещение на четыре ( перескочить int a, и читаем 4 байта за ним - это и будет int b. а теперь представь, что было бы если там лежала на живая структура, а указатель на нее , а сама она находилась бы в другом месте памяти? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 14:25 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
Где-то в степи, удобно да. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 14:32 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
а теперь представим, что зл..й уборщик мусора дефрагментировал разряженную кучу, все адреса пер...блись, а у нас в массиве лежат адреса старые, что он будет делать? кончено менять на новые, а нах ему это надо, а тупой проггер заставил его... ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 14:36 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
Изопропилоткуда этот бред? дальше даже читать неинтересно Сколько в граммах будет весить объекта класса в момент исполнения? Код: c# 1. 2. 3.
... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 15:12 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
ЕвгенийВИзопропилоткуда этот бред? дальше даже читать неинтересно Сколько в граммах будет весить объекта класса в момент исполнения? Код: c# 1. 2. 3.
Код: c# 1.
почему только в момент исполнения? так же как и в случае структур, IntPtr может иметь разный размер в x86/x64 реальные размеры вычисляются при загрузке метаданных класса/структуры ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 16:19 |
|
Generic List of structs
|
|||
---|---|---|---|
#18+
ИзопропилЕвгенийВпропущено... Сколько в граммах будет весить объекта класса в момент исполнения? Код: c# 1. 2. 3.
Код: c# 1.
почему только в момент исполнения? так же как и в случае структур, IntPtr может иметь разный размер в x86/x64 реальные размеры вычисляются при загрузке метаданных класса/структуры авторНевозможно упаковать тип "ConsoleApplication3.Изопропил" как неуправляемую структуру; невозможно вычислить размер или смещение, имеющие смысл. в System.Runtime.InteropServices.Marshal.SizeOfHelper(Type t, Boolean throwIfNotMarshalable) в System.Runtime.InteropServices.Marshal.SizeOf(Type t) в System.Runtime.InteropServices.Marshal.SizeOf[T]() в ConsoleApplication3.MainApp.Main() в D:\EvProjects\My\ConsoleApplication1\ConsoleApplication3\Program.cs:строка 18 в System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) в System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) в Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() в System.Threading.ThreadHelper.ThreadStart_Context(Object state) в System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) в System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) в System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) в System.Threading.ThreadHelper.ThreadStart() ... |
|||
:
Нравится:
Не нравится:
|
|||
05.08.2016, 17:03 |
|
|
start [/forum/topic.php?all=1&fid=20&tid=1400412]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
11ms |
check topic access: |
11ms |
track hit: |
37ms |
get topic data: |
13ms |
get forum data: |
2ms |
get page messages: |
65ms |
get tp. blocked users: |
1ms |
others: | 273ms |
total: | 434ms |
0 / 0 |