addrange c что это
Список.Субоптимальная реализация AddRange
вы видите какие-либо причины не использовать эту более простую и, по-видимому, более быструю альтернативу?
Edit:
Edit 2:
я реализовал класс FastList, идентичный List, За исключением того, что он также обеспечивает перегрузку AddRange, которая занимает T[] аргумент. Эта перегрузка не требует проверки динамического типа и двойного копирования элементов. Я сделал профиль этого FastList.AddRange против списка.AddRange путем добавления 4-байтовых массивов 1000 раз в список, который изначально был emtpy. Моя реализация превосходит скорость стандартного списка.AddRange с коэффициентом 9 (девять!). Список.AddRange занимает около 5% времени выполнения в одном из важных сценариев использования нашего приложения, замена List классом, обеспечивающим более быстрый AddRange, может улучшить приложение на 4%.
3 ответов
они препятствуют осуществлению ICollection доступ к индексам списка назначения за пределами вставки. Реализация выше приводит к IndexOutOfBoundsException если неисправная (или» манипулятивная») реализация CopyTo называется.
Это хороший вопрос, я пытаюсь придумать причину. В справочном источнике нет никаких намеков. Одна из возможностей заключается в том, что они пытаются избежать проблемы, когда класс, реализующий ICollection.Объекты метода CopyTo () против копирования в начальный индекс, отличный от 0. Или в качестве меры безопасности, препятствующей коллекции возиться с элементами массива, к которым она не должна иметь доступа.
еще один заключается в том, что это счетчик, когда используется коллекция в потоке-небезопасным способом. Если элемент был добавлен в коллекцию другим потоком, это будет метод CopyTo() класса коллекции, который завершается неудачей, а не код Microsoft. Правильный человек получит вызов службы.
Это не большие объяснения.
существует проблема с вашим решением, если вы подумаете об этом в течение минуты, если вы измените код таким образом, вы по существу даете коллекцию, которая должна быть добавлена доступ к внутренней структуре данных.
Это не очень хорошая идея, например, если автор списка datastructure выясняет лучшую базовую структуру для хранения данных, чем массив, нет никакого способа изменить реализацию списка, так как вся коллекция ожидает массив в Функция копировать, чтобы.
по сути, вы бы цементировали реализацию класса List, даже если объектно-ориентированное программирование говорит нам, что внутренняя реализация datastructure должна быть чем-то, что можно изменить, не нарушая другой код.
Http Web Request. Add Range Метод
Определение
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Добавляет в запрос заголовок диапазона.
Перегрузки
Добавляет в запрос заголовок диапазона байтов для определенного диапазона, располагающегося с начала или с конца запрашиваемых данных.
Добавляет в запрос заголовок диапазона байтов для определенного диапазона, располагающегося с начала или с конца запрашиваемых данных.
Добавляет в запрос заголовок диапазона байтов для заданного диапазона.
Добавляет в запрос заголовок диапазона байтов для заданного диапазона.
Добавляет в запрос заголовок Range для определенного диапазона, располагающегося с начала или с конца запрашиваемых данных.
Добавляет в запрос заголовок Range для определенного диапазона, располагающегося с начала или с конца запрашиваемых данных.
Добавляет в запрос заголовок диапазона для заданного диапазона.
Добавляет в запрос заголовок диапазона для заданного диапазона.
Комментарии
Так как все сущности HTTP представлены в сообщениях HTTP как последовательности байтов, понятие диапазона байтов имеет смысл для любой сущности HTTP. Однако не все клиенты и серверы должны поддерживать операции с диапазонами байтов.
Заголовок Range в запросе позволяет клиенту запросить, чтобы он получал некоторую часть указанного диапазона байтов в сущности HTTP. Серверы не должны поддерживать запросы заголовков диапазонов.
AddRange(Int32)
Добавляет в запрос заголовок диапазона байтов для определенного диапазона, располагающегося с начала или с конца запрашиваемых данных.
Параметры
Начальная или конечная точка диапазона.
Исключения
Не удалось добавить заголовок диапазона.
Примеры
В следующем примере кода в запрос добавляется заголовок диапазона.
Комментарии
HttpWebRequest.AddRangeМетод добавляет в запрос заголовок диапазона байтов.
Если range аргумент имеет положительное значение, range параметр задает начальную точку диапазона. Сервер должен начать отправку данных из range параметра, указанного в конец данных в СУЩНОСТИ HTTP.
Если range имеет отрицательное значение, range параметр задает конечную точку диапазона. Сервер должен начать отправку данных с начала данных в сущности HTTP в range указанный параметр.
Так как все сущности HTTP представлены в сообщениях HTTP как последовательности байтов, понятие диапазона байтов имеет смысл для любой сущности HTTP. Однако не все клиенты и серверы должны поддерживать операции с диапазонами байтов.
Заголовок Range в запросе позволяет клиенту запросить, чтобы он получал некоторую часть указанного диапазона байтов в сущности HTTP. Серверы не должны поддерживать запросы заголовков диапазонов.
Пример заголовка диапазона в запросе протокола HTTP, запрашивающего сервер, который отправляет первые 100 байт (от начала до байта 99), будет выглядеть следующим образом:
В этом примере range параметр равен-99.
HTTP-сервер указывает на поддержку заголовков диапазонов с заголовком Accept-Ranges. Ниже приведен пример заголовка Accept-Ranges с сервера, который поддерживает диапазоны байтов.
Если заголовок Accept-Ranges не получен в заголовке ответа сервера, то сервер не поддерживает заголовки диапазонов. Пример заголовка Accept-Ranges с сервера, который не поддерживает диапазоны, но распознает заголовок Accept-Ranges, будет выглядеть следующим образом:
При получении ответа из запроса диапазона анализируются только заголовки HTTP, связанные со всем запросом, и становятся доступными через свойства HttpWebResponse класса. Заголовки, связанные с каждым диапазоном, возвращаются в ответе.
См. также раздел
Применяется к
AddRange(Int64)
Добавляет в запрос заголовок диапазона байтов для определенного диапазона, располагающегося с начала или с конца запрашиваемых данных.
Параметры
Начальная или конечная точка диапазона.
Исключения
Не удалось добавить заголовок диапазона.
Комментарии
HttpWebRequest.AddRangeМетод добавляет в запрос заголовок диапазона байтов.
Если range аргумент имеет положительное значение, range параметр задает начальную точку диапазона. Сервер должен начать отправку данных из range параметра, указанного в конец данных в СУЩНОСТИ HTTP.
Если range имеет отрицательное значение, range параметр задает конечную точку диапазона. Сервер должен начать отправку данных с начала данных в сущности HTTP в range указанный параметр.
Так как все сущности HTTP представлены в сообщениях HTTP как последовательности байтов, понятие диапазона байтов имеет смысл для любой сущности HTTP. Однако не все клиенты и серверы должны поддерживать операции с диапазонами байтов.
Заголовок Range в запросе позволяет клиенту запросить, чтобы он получал некоторую часть указанного диапазона байтов в сущности HTTP. Серверы не должны поддерживать запросы заголовков диапазонов.
Пример заголовка диапазона в запросе протокола HTTP, запрашивающего сервер, который отправляет первые 100 байт (от начала до байта 99), будет выглядеть следующим образом:
В этом примере range параметр равен-99.
HTTP-сервер указывает на поддержку заголовков диапазонов с заголовком Accept-Ranges. Ниже приведен пример заголовка Accept-Ranges с сервера, который поддерживает диапазоны байтов.
Если заголовок Accept-Ranges не получен в заголовке ответа сервера, то сервер не поддерживает заголовки диапазонов. Пример заголовка Accept-Ranges с сервера, который не поддерживает диапазоны, но распознает заголовок Accept-Ranges, будет выглядеть следующим образом:
При получении ответа из запроса диапазона анализируются только заголовки HTTP, связанные со всем запросом, и становятся доступными через свойства HttpWebResponse класса. Заголовки, связанные с каждым диапазоном, возвращаются в ответе.
См. также раздел
Применяется к
AddRange(Int32, Int32)
Добавляет в запрос заголовок диапазона байтов для заданного диапазона.
Параметры
Место начала передачи данных.
Место остановки передачи данных.
Исключения
-или- Значение параметра from или to меньше 0.
Не удалось добавить заголовок диапазона.
Примеры
В следующем примере кода в запрос добавляется заголовок диапазона.
Комментарии
HttpWebRequest.AddRangeМетод добавляет в запрос заголовок диапазона байтов.
Так как все сущности HTTP представлены в сообщениях HTTP как последовательности байтов, понятие диапазона байтов имеет смысл для любой сущности HTTP. Однако не все клиенты и серверы должны поддерживать операции с диапазонами байтов.
Заголовок Range в запросе позволяет клиенту запросить, чтобы он получал некоторую часть указанного диапазона байтов в сущности HTTP. Серверы не должны поддерживать запросы заголовков диапазонов.
Пример заголовка диапазона в запросе протокола HTTP, который запрашивает первые 100 байт, будет выглядеть следующим образом:
В этом примере параметр будет from указан как 0, а to параметр будет указан как 99. Этот метод автоматически задает для спецификатора диапазона значение «байт».
HTTP-сервер указывает на поддержку заголовков диапазонов с заголовком Accept-Ranges. Ниже приведен пример заголовка Accept-Ranges с сервера, который поддерживает диапазоны байтов.
Если заголовок Accept-Ranges не получен в заголовке ответа сервера, то сервер не поддерживает заголовки диапазонов. Пример заголовка Accept-Ranges с сервера, который не поддерживает диапазоны, но распознает заголовок Accept-Ranges, будет выглядеть следующим образом:
При получении ответа из запроса диапазона анализируются только заголовки HTTP, связанные со всем запросом, и становятся доступными через свойства HttpWebResponse класса. Заголовки, связанные с каждым диапазоном, возвращаются в ответе.
См. также раздел
Применяется к
AddRange(Int64, Int64)
Добавляет в запрос заголовок диапазона байтов для заданного диапазона.
Параметры
Место начала передачи данных.
Место остановки передачи данных.
Исключения
-или- Значение параметра from или to меньше 0.
Не удалось добавить заголовок диапазона.
Комментарии
HttpWebRequest.AddRangeМетод добавляет в запрос заголовок диапазона байтов.
Так как все сущности HTTP представлены в сообщениях HTTP как последовательности байтов, понятие диапазона байтов имеет смысл для любой сущности HTTP. Однако не все клиенты и серверы должны поддерживать операции с диапазонами байтов.
Заголовок Range в запросе позволяет клиенту запросить, чтобы он получал некоторую часть указанного диапазона байтов в сущности HTTP. Серверы не должны поддерживать запросы заголовков диапазонов.
Пример заголовка диапазона в запросе протокола HTTP, который запрашивает первые 100 байт, будет выглядеть следующим образом:
В этом примере параметр будет from указан как 0, а to параметр будет указан как 99. Этот метод автоматически задает для спецификатора диапазона значение «байт».
HTTP-сервер указывает на поддержку заголовков диапазонов с заголовком Accept-Ranges. Ниже приведен пример заголовка Accept-Ranges с сервера, который поддерживает диапазоны байтов.
Если заголовок Accept-Ranges не получен в заголовке ответа сервера, то сервер не поддерживает заголовки диапазонов. Пример заголовка Accept-Ranges с сервера, который не поддерживает диапазоны, но распознает заголовок Accept-Ranges, будет выглядеть следующим образом:
При получении ответа из запроса диапазона анализируются только заголовки HTTP, связанные со всем запросом, и становятся доступными через свойства HttpWebResponse класса. Заголовки, связанные с каждым диапазоном, возвращаются в ответе.
См. также раздел
Применяется к
AddRange(String, Int32)
Добавляет в запрос заголовок Range для определенного диапазона, располагающегося с начала или с конца запрашиваемых данных.
Параметры
Начальная или конечная точка диапазона.
Исключения
Не удалось добавить заголовок диапазона.
Комментарии
HttpWebRequest.AddRangeМетод добавляет к запросу заголовок диапазона.
Если range аргумент имеет положительное значение, range параметр задает начальную точку диапазона. Сервер должен начать отправку данных из range параметра, указанного в конец данных в СУЩНОСТИ HTTP.
Если range имеет отрицательное значение, range параметр задает конечную точку диапазона. Сервер должен начать отправку данных с начала данных в сущности HTTP в range указанный параметр.
Так как все сущности HTTP представлены в сообщениях HTTP как последовательности байтов, понятие диапазона байтов имеет смысл для любой сущности HTTP. Однако не все клиенты и серверы должны поддерживать операции с диапазонами байтов.
Заголовок Range в запросе позволяет клиенту запросить, чтобы он получал некоторую часть указанного диапазона байтов в сущности HTTP. Серверы не должны поддерживать запросы заголовков диапазонов.
rangeSpecifier Обычно параметр задается как «bytes», так как это единственный описатель диапазона, распознаваемый большинством HTTP-серверов. Присвоение rangeSpecifier параметру другой строки обеспечивает поддержку настраиваемых описателей диапазона, отличных от байтов (спецификатор диапазона байтов, определенный в RFC 2616 консорциумом IETF).
Пример заголовка диапазона в запросе протокола HTTP, который запрашивает первые 100 байт, будет выглядеть следующим образом:
В этом примере параметр будет rangeSpecifier указан как «bytes», а range параметр — значение-99.
HTTP-сервер указывает на поддержку заголовков диапазонов с заголовком Accept-Ranges в ответе. Ниже приведен пример заголовка Accept-Ranges с сервера, который поддерживает диапазоны байтов.
Если заголовок Accept-Ranges не получен в заголовке ответа сервера, то сервер не поддерживает заголовки диапазонов. Пример заголовка Accept-Ranges с сервера, который не поддерживает диапазоны, но распознает заголовок Accept-Ranges, будет выглядеть следующим образом:
При получении ответа из запроса диапазона анализируются только заголовки HTTP, связанные со всем запросом, и становятся доступными через свойства HttpWebResponse класса. Заголовки, связанные с каждым диапазоном, возвращаются в ответе.
Почему AddRange быстрее, чем использование цикла foreach?
ОТВЕТЫ
Ответ 1
Ответ 2
Я ожидаю, что он радикально изменится (больше не изменится/копирование данных).
Из отражателя AddRange делает это внутренне, а не растет в удвоении:
Ответ 3
Поскольку AddRange проверяет размер добавленных элементов и увеличивает размер внутреннего массива только один раз.
Ответ 4
Разборка из отражателя для метода List AddRange имеет следующий код
Как вы видите, есть некоторые оптимизации, такие как вызов EnsureCapacity() и использование Array.Copy().
Ответ 5
При использовании AddRange коллекция может увеличить размер массива один раз, а затем скопировать значения в него.
Увеличение размера thr означает копирование полного массива, требующего времени.
Ответ 6
Это похоже на то, как просить официанта десять раз выпить вам пива и попросить его немедленно принести вам 10 пива.
Как вы думаете, быстрее?)
Ответ 7
Я предполагаю, что это результат оптимизации распределения памяти. для памяти AddRange выделяется только один раз, и в то время как foreach на каждой итерации выполняется перераспределение.
также могут быть некоторые оптимизации в реализации AddRange (например, memcpy)
Ответ 8
Попробуйте инициализировать емкость внутреннего списка перед добавлением вручную элементов:
Ответ 9
Это потому, что цикл Foreach добавит все значения, которые цикл получает один раз, и
метод AddRange() соберет все значения, которые он получает как «кусок», и сразу добавит этот фрагмент в указанное место.
Просто понимайте, это похоже на то, что у вас есть список из 10 предметов, которые можно вывести с рынка, что будет быстрее приносить все это за один или все за один раз.
Ответ 10
Функциональность с Range в ObservableCollection
Класс ObservableCollection не позволяет добавлять, удалять и т.д. коллекции элементов.
Чтобы добавить такую функциональность можно создать потомок этого класса, в котором реализовать необходимый функционал.
Цель:
Избежать множественных событий PropertyChanged и OnCollectionChanged при массовых изменениях коллекции, а выигрыш по синтаксису практически незначительный и роли не играет.
В ObservableCollection есть унаследованное от Collection свойство:
с которым и необходимо работать.
Шаблон доработки такой:
1) Проверить на возможность изменения:
2) Обработать элементы согласно вашей логике:
3) Вызвать событие PropertyChanged для свойств «Count» и «Item[]»:
4) Вызвать событие CollectionChanged с параметрами события: тип изменения Reset, параметры OldItems и NewItems не передавать:
Недостатки:
Из-за п.4 в обработчике события CollectionChanged невозможно будет работать с OldItems и NewItems так как они пустые. Это необходимо из-за того, что некоторые контролы WPF не работают с изменениями коллекции не по одному элементу, а по несколько. При этом, если тип изменения Reset, то это означает что произошло существенно изменение коллекции, и для контролов WPF это нормально. Если же вы используете новый класс не в качестве источника данных для контрола WPF, то можно в п.4 передавать и другие типы изменений, а также заполненные значения OldItems и NewItems и затем спокойно их обрабатывать.
C# List AddRange Use
AddRange adds an entire collection of elements.
It can replace tedious foreach-loops that repeatedly call Add on List. We can pass any IEnumerable collection to AddRange, not just an array or another List.
Example. We look at the AddRange instance method from the base class library in the C# language on List. This example adds a range at the end of the List using the AddRange method. The term «range» simply means an IEnumerable collection.
We see a new List created, and four ints added to it. Then, an array of three elements of the same numeric type is initialized. We then call AddRange as an instance method on List. It receives the array.
Result: It displays seven integers, which are the union of the List itself and the array we added with AddRange.
Internals. I wanted to know how AddRange and its friend InsertRange do in the runtime. I found that AddRange is a wrapper method on top of InsertRange. More information on the implementation of InsertRange is available.
Performance. First, we know that AddRange and InsertRange are internally the same method. Second, we know from the compiled code above that the internal implementation normally calls Array.Copy or CopyTo.
Therefore: It is impossible for AddRange or InsertRange to perform better than a plain Array.Copy.
However: Array.Copy itself may perform better than manually copying elements in a loop.
Summary. AddRange appends a range of values to the end of a List. InsertRange, on the other hand, can insert an array between the elements in a List. These two methods provide a convenient interface to List range manipulations.