Обработка большого количества элементов в SharePoint
В сегодняшнем посте я продолжу писать о производительности при работе со списками/библиотеками документов в SharePoint. На этот раз массовое создание/изменение/удаление элементов. И все это в трех вариантах:
- Стандартный функционал SharePoint (
SPListItem.Update()
,SPListItem.Delete()
); - Мой любимый Linq to SharePoint;
- Batch-команды (
SPWeb.ProcessBatchData()
).
Тестовая среда
Для тестирования я использовал все ту же модель данных, описанную мною в одном из постов о Linq to SharePoint. На узле в списке Employees были сгенерированы около 10.000 элементов.
Методика тестирования
Использую выше описанные подходы к управлению данными в SharePoint я последовательно выполнял операции создания/изменения/удаления элементов списка. Кол-во элементов, которые подвергались обработке было от 10 до 1000. Т.к. только в случае с batch-командами можно говорить о пакетной обработке, в остальных случаях можно будет только добиться "провисания" производительности.
Так как технологии работы с данными SharePoint, представленные здесь, различаются, я опишу то, как я их использовал.
Для подведения итогов я брал затраченное время в пересчете на один элемент.
SPListItem
Здесь, я думаю, даже пояснять не стоит. SharePont как он есть:
- using (var site = new SPSite(siteUrl))
- {
- using (var web = site.OpenWeb())
- {
- web.AllowUnsafeUpdates = true;
- var list = web.Lists["Employees"];
- var item = list.Items.Add(); //item.GetItemById(itemId);
- item["Title"] = RandomString(30);
- //...
- item.Update(); //item.Delete();
- }
- }
Linq to SharePoint
И в этом случае все тоже без изысков. Я бы здесь отметил удобство использования Linq to SharePoint при удалении коллекции объектов:
- using (var ctx = new ZhukDataContext(siteUrl))
- {
- var employees = ctx.Employees.Take(qnt);
- ctx.Employees.DeleteAllOnSubmit(employees);
- ctx.SubmitChanges();
- }
Batch используя Linq to SharePoint
Здесь я использовал Linq to SharePoint для построения batch-команд, которые в последствии передавались методу SPWeb.ProcessBatchData(). Подробнее о формировании batch-команд в Linq to SharePoint здесь.
Создание элементов
![](/imagelibrary/SPPerformanceCreatingChart.png)
На диаграмме видно, что производительность при создании элементов списка не "провисает" при большом количестве создаваемых элементов. При использовании Linq to SharePoint для повышения производительность (более чем два раза!) лучше использовать batch-команды. А вот чем обоснован "проигрыш" Linq to SharePoint при создании элементов я объяснить не могу.
Вывод
Linq to SharePoint ОЧЕНЬ медленно работает при создании элементов. При построении репозиториев на базе Linq to SharePoint лучше использовать batch-команды для создания элементов.
Изменение элементов
![](/imagelibrary/SPPerformanceEditingChart.png)
Здесь тенденция во всех случаях одна: чем больше элементов изменяется, тем меньше времени расходуется на один элемент. Интересно ещё и то, что пакетная обработка файлов дает прирост производительности только в том случае, когда обрабатываемых элементов более тысячи. Здесь конечно стоит сослаться на то, что генерация batch-команд в моем тесте происходит на основе рефлексии. И я рискну предположить, что в случае, когда генерация batch-команд будет проходить путем простой конкатенации строк, то прирост производительности мы получим уже при 100 элементах.
Вывод
Изменение элементов - тот случай, когда batch-команды не добавляют производительности. Linq to SharePoint и здесь медлителен. Но без этой "обертки" все равно никуда не деться, т.к. мапинг полей элемента списка на класс бизнес модели нужен всегда.
Удаление элементов
![](/imagelibrary/SPPerformanceDeletingChart.png)
Вот случай когда использование batch-команд крайне оправдано. К тому же рефлексия при генерации batch-команд не используется. И ещё очень интересный момент Linq to SharePoint справляется с удалением элементов из списка/библиотеки гораздо быстрее чем "SPListItem".
Вывод
При удалении элементов в случае, когда объект SPWeb инициализирован быстрее всего будет сформировать batch-команду и исполнить её, передав в качестве параметра методу ProcessBatchData.