| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Общие вопросы по .NET и C# > Как можно увеличить размер массива? |
| Автор: ivashkanet 23.2.2006, 18:55 | ||||
| Как можно увеличить размер массива? Задача: Есть некоторый массив объектов, изначально пустой. Нужно получить эффективную возможность добавления нового элемента в массив. Задачу можно решить так:
Но поэлементное присваивание не очень эффективно. Хотелось бы что нибудь вроде
Но при использовании Clases = Temp в массив Clases передается не только элементы массива Temp, но и его размер. |
| Автор: Illuminaty 23.2.2006, 20:36 |
| A готовый класс http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemcollectionsarraylistclasstopic.asp не подойдет? |
| Автор: ivashkanet 23.2.2006, 21:18 |
| Спасибо, Illuminaty, очень даже подошло! P.S. Пока разбирался с ArrayList, нашел класс Hashtable, который подошел еще больше! Спаибо. |
| Автор: Illuminaty 23.2.2006, 21:52 |
| Пожалуйста Заходи еще |
| Автор: mr.DUDA 23.2.2006, 22:42 |
| Эффективно увеличивать размер массива невозможно, если только массив не растёт с упреждающей скоростью. Поясню на примере: есть массив длиной 10 элементов. Надо добавить 11-й элемент. В памяти все 10 элементов идут друг за другом (так организован массив). Чтобы добавить 11-й, система создаёт новый пустой массив длиной в 11 элементов, копирует каждый элемент (что там у нас - ссылки на объекты C#, указатели на объекты C++, объекты С++, или что бы там ни было) в новый массив, и добавляет 11-й элемент в пустое место в конце массива. Вот так вот. Для оптимизации можно использовать алгоритм упреждающего резервирования: при выделении памяти на N элементов, всегда оставлять место для M дополнительных элементов. Именно так работает контейнер vector<T> в С++. Именно так организуется коллекция ArrayList в C#. |
| Автор: ivashkanet 4.3.2006, 01:18 | ||||||||||||||
mr.DUDA, большое спасибо. Вещь не просто классная, она крутая Так вот, с ее помощью дезассемблировал класс ArrayList. Вот основные процедуры:
Процедура добавляет новый элемент к массиву. Если у нас зарезервировано место в массиве(а резервируется прилично), то все пучком. Если нет то тоже не беда: работает EnsureCapacity. (Хоть это и функция (return int), лучше назвать её процедера, так как я не думаю, что возвращаемое значение можно где-то использовать
То же все предельно просто. Та самая
упреждающая скорость. Причем не хилая: 2-х кратный запас ячеек. (Так как они все null , то потери памяти нет (я не специалист но мне так кажется. Поправте меня, пожалуйста, если я ошибаюсь.)
Свойство-функция (метод или как они там называются), которая реально и увеличивает размер (емкость) массива.
Метод перенаправляет нас на другой перегруженный метод, который копирует все элементы одного массива в другой (почему нельзя было обойтись без него не знаю. Скорее всего проблема с доступом (я в этом пока не очень) первый метод public, в второй internal).
Очень интересная процедура, как она работает и где это она extern -- не известно. Но ясно одно -- как бы там она не работала, она работает, в среднем, в полтора раза быстрее, чем поэлементное копирование. Выводы: 1. Основной прирост скорости работы происходит из-за роста массива с упреждающей скоростью. 2. Используется "неизвестная" процедура Copy. Может это ноу-хау M$, хотя на мой взгляд ноу-хау в таких элементарных вопросах (копирование массивов) уже давно нет. Скорее всего она написана каким-то "хитрым кодом", и скорее всего написать его с помощью C# нельзя P.S. Надеюсь статья кому нибудь понравится. Еще раз спасибо, mr.DUDA, за Reflector. Знаю ее всего 2 дня, а уже люблю. P.P.S. Исправьте меня, если я где-то не прав |
| Автор: mr.DUDA 4.3.2006, 10:45 | ||||
Ну место-то для объектов выделяется. Если это структуры, то память будет выделена сразу по N байт для M структур, если объекты - то по 4 байта для M объектов. Может и не 4, т.к. что там реально в Array хранится - одному CLR'у известно.
Скорее всего дёргается memcpy ... |
| Автор: -ser- 4.3.2006, 11:29 | ||||
| как generic альтернативу ArrayList можно использовать List<T> я полагал что у обоих механизм добавления элемента работает аналогично. но вот что они пишут
допустим, но читаем дальше
так почему в первом случае они не упоминали "and copying"? я подумал, может в случае с генериками они используют внутренний индекс? хотя тогда почему бы его не использовать и в случае уменьшения размера. |
| Автор: ivashkanet 4.3.2006, 17:27 |
| А что такое memcpu??? |
| Автор: ivashkanet 4.3.2006, 22:39 |
| Классно!!! Я получил 1 балл репутации. Но только вот что это, и кто мне его дал??? (Ну и естественно за что?) Объясните, пожалуйста. P.S. Что мне мешает создать нового юзера и "наплюсить" себу репутации???? |
| Автор: arilou 5.3.2006, 01:14 | ||
| ivashkanet, вот такая вот фигня, ой, атрибут вобщем,
означает, что реализация метода находится "внутри" инфраструктуры фреймворка, и написана она в unmanaged коде. Можешь скачать ROTOR (реализация CLR, доступная под лицензией shared source), и посмотреть. Там очень много методов "MethodImplOptions.InternalCall" http://msdn.microsoft.com/net/sscli/ |
| Автор: ivashkanet 5.3.2006, 11:18 |
| Спасибо, arilou, но мне хватит и .Net. А в дебри CLR я пока лезть не хочу. Маленький (в смысле новичок) ещё |
| Автор: ivashkanet 15.12.2006, 08:51 |
| Страшный, вопиющий Но это мое первое сообщение/тема на форуме |