Что более эффективно: List <T>.Add () или System.Array.Resize ()? - PullRequest
10 голосов
/ 18 января 2011

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

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

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

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

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

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

Ответы [ 5 ]

20 голосов
/ 18 января 2011

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

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

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

2 голосов
/ 18 января 2011

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

Я мог бы сравнить эту производительность с развернутым связанным списком, упомянутым в библиотеке powertools, здесь: Любая реализация развернутого связанного списка в C #?

0 голосов
/ 11 июня 2017

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

0 голосов
/ 22 февраля 2013

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

0 голосов
/ 17 мая 2011

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

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

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

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

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

...