2011-01-18 2 views
9

Я пытаюсь определить, когда это более эффективно для List<T>.Add() по сравнению с использованием метода Array.Resize().Что более эффективно: Список <T> .Add() или System.Array.Resize()?

Документация для Array.Resize говорит, что она копирует весь массив и помещает его в новый объект. Старый объект должен быть отброшен. Где находится этот старый объект? В стеке или куче?

Я не знаю, как работает List.Add().

Кто-нибудь знает, как метод List.Add сравнивается со статическим методом Array.Resize?

Меня интересует использование памяти (и очистка), и что лучше для 300 типов значений по сравнению с 20 000 типов значений.

Для чего это стоит, я планирую запустить этот код на одном из внедренных ароматов .NET. Потенциально .NET Gadgeteer

+3

Нет проблем с боксом. Не заново изобретайте колесо. 'Список ' существует по какой-либо причине; используй это! – SLaks

+0

У меня было ощущение, что список был ответом на что-то более 500 объектов, но мне любопытно узнать это (поиск по 500) http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx – LamonteCristo

+0

Есть ли бокс проблемы с System.Array? – LamonteCristo

ответ

20

Вы должны использовать List<T>.

Использование Array.Resize заставит вас развернуть массив отдельно каждый раз, когда вы добавляете элемент, делая свой код much slower. (так как массивы не могут иметь запасную емкость)

A List<T> подкрепляется массивом, но содержит запасную емкость для ввода предметов.
Все, что нужно сделать, чтобы добавить элемент, - это установить элемент в массиве и увеличить его внутренний счетчик size.
Когда массив будет заполнен, список удвоит его емкость, что позволит добавлять новые элементы снова и снова.

+0

Мне интересно, что лучше всего подходит для 300 объектов, так как MSDN говорит, что список платит за себя около 500 объектов – LamonteCristo

+0

Иду дальше, я буду создавать множество массивов из 300 объектов, и поэтому понимание этой оптимизации может быть полезным, а не просто академический. – LamonteCristo

+0

Это по сравнению с 'ArrayList', которого следует избегать любой ценой (поскольку он не является универсальным и требует отбрасываний и бокса). Кроме того, 500 предметов не обязательно должны быть в одном списке. Если у вас есть два списка, он все равно окупится. – SLaks

2

.NET Micro Framework не поддерживает дженерики, поэтому я буду использовать массив, копируя и уничтожая его по мере необходимости.

я мог бы сравнить, что perfmance к развернутому связанному списку, указанному в библиотеке электроинструментов здесь: Any implementation of an Unrolled Linked List in C#?

0

В .NET Framework Micro не делает (пока) поддержку генерик. Вы ограничены в отношении динамических коллекций.

Одна вещь, которую следует учитывать при выборе вашего подхода, состоит в том, что управляемый код на микроконтроллере очень и очень медленный. Многие операции в управляемых объектах .NET Micro Framework на самом деле просто вызываются в собственный код для выполнения этой работы. Это намного быстрее.

Например, сравните копирование элемента массива по элементу в цикле for и вызове Array.Copy(), который по существу делает то же самое, что и в собственном коде.

По возможности используйте эти родные расширения, чтобы получить лучшую производительность. Также рассмотрите возможность взглянуть на код MicroLinq project на CodePlex. Существует дополнительный проект, посвященный только расширенным коллекциям NETMF (также доступен как NuGet package). Код свободно доступен и открыто лицензируется для любых целей. (Полное раскрытие: я являюсь разработчиком этого проекта.)

Если вы можете уйти с распределением большого массива и отслеживанием максимального положения, на котором были сохранены реальные данные, это было бы самым быстрым, но требует больше работы/мысли, внесенных в дизайн, и забирает время от создания классных вещей.

0

Список будет быстрее, если вы часто изменяете размер массива, например, каждый раз, когда вы добавляете элемент. Однако, если вы изменяете размер каждого кадра, список и встроенные массивы должны быть эквивалентны, возможно, массивы еще быстрее.

0

Я видел реализацию списка после декомпиляции и обнаружил, что для внутреннего массива он использует Array.Resize(). Но он управляет счетчиком элементов и использует длину массива как емкость и изменяет размер массива с некоторым дополнительным пространством при вызове Add(). Итак, я думаю, вы можете разработать более оптимальную стратегию распределения, чем List для вашего дела. Но вам придется управлять элементами счетчика вручную. Также вы избавитесь от накладных индексаторов при доступе к элементам массива, потому что индексаторы внутри списка - это просто методы, которые запрашивают внутренние элементы массива. Я думаю, что стоит заменить List by array на ручной размер, если это узкое место.

 Смежные вопросы

  • Нет связанных вопросов^_^