Обработка большого количества элементов в 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 здесь.
Создание элементов
На диаграмме видно, что производительность при создании элементов списка не "провисает" при большом количестве создаваемых элементов. При использовании Linq to SharePoint для повышения производительность (более чем два раза!) лучше использовать batch-команды. А вот чем обоснован "проигрыш" Linq to SharePoint при создании элементов я объяснить не могу.
Вывод
Linq to SharePoint ОЧЕНЬ медленно работает при создании элементов. При построении репозиториев на базе Linq to SharePoint лучше использовать batch-команды для создания элементов.
Изменение элементов
Здесь тенденция во всех случаях одна: чем больше элементов изменяется, тем меньше времени расходуется на один элемент. Интересно ещё и то, что пакетная обработка файлов дает прирост производительности только в том случае, когда обрабатываемых элементов более тысячи. Здесь конечно стоит сослаться на то, что генерация batch-команд в моем тесте происходит на основе рефлексии. И я рискну предположить, что в случае, когда генерация batch-команд будет проходить путем простой конкатенации строк, то прирост производительности мы получим уже при 100 элементах.
Вывод
Изменение элементов - тот случай, когда batch-команды не добавляют производительности. Linq to SharePoint и здесь медлителен. Но без этой "обертки" все равно никуда не деться, т.к. мапинг полей элемента списка на класс бизнес модели нужен всегда.
Удаление элементов
Вот случай когда использование batch-команд крайне оправдано. К тому же рефлексия при генерации batch-команд не используется. И ещё очень интересный момент Linq to SharePoint справляется с удалением элементов из списка/библиотеки гораздо быстрее чем "SPListItem".
Вывод
При удалении элементов в случае, когда объект SPWeb инициализирован быстрее всего будет сформировать batch-команду и исполнить её, передав в качестве параметра методу ProcessBatchData.