Как вы обрабатываете свои XML-данные? С помощью LINQ to XML, XPath, XmlDocument или же сами парсите (тогда вам пора в больничку). Лично я предпочитаю писать XPath-выражение, потому что они (относительно) просты в написании и, соответственно, в чтении. Да и скорость обработки этих выражений всегда радовала своей производительностью. Какое-то время назад вышел extension для LINQ to XML, позволяющий использовать XPath выражения.
Небольшой эксперимент позволил определить плюсы и минусы нового расширения по сравнению с LINQ to XML. Для начала я спер базу AdventureWorks и экспортировал данные из таблицы SalesOrderDetail в xml файлик. 120000 строк мне показались достаточным набором данных для подобного теста.
Затем я написал три различных запроса к этому набору данных с использованием LINQ to XML и тожесамое + XPath. Код и результаты тестов прилагаются.
LINQ to XML: 246.96 мс
/// <summary>
/// Выбираем все элементы для ордера с ID=46348
/// </summary>
public static int RunQuery1(XDocument xDoc)
{
IEnumerable<XElement> elements =
from result in xDoc.Descendants("dataroot").Descendants("SalesOrderDetail")
where result.Element("SalesOrderID").Value == "46348"
select result;
return elements.Count();
}
LINQ to XML с XPath: 1025.95 мс
public static int RunQuery1(XDocument xDoc)
{
return xDoc.XPathSelectElements("//dataroot/SalesOrderDetail[SalesOrderID=46348]").Count();
}
Правда код с использованием XPath выглядит элегантнее? ОК, идем дальше.
LINQ to XML: 208.88 мс
/// <summary>
/// Считаем все SalesOrderDetailы частота заказов > 2 для ProductID=761
/// </summary>
public static int RunQuery2(XDocument xDoc)
{
IEnumerable<XElement> elements =
from result in xDoc.Descendants("dataroot").Descendants("SalesOrderDetail")
where String.CompareOrdinal(result.Element("OrderQty").Value, "2") > 0
&& result.Element("ProductID").Value == "761"
select result;
return elements.Count();
}
LINQ to XML сXPath: 1013.19 мс
public static int RunQuery2(XDocument xDoc)
{
return xDoc.XPathSelectElements("//dataroot/SalesOrderDetail[OrderQty>2 and ProductID=761]").Count();
}
LINQ to XML: 218.37 мс
/// <summary>
/// Считаем все SalesOrderDetailы, где LineTotal > $4000
/// </summary>
public static int RunQuery3(XDocument xDoc)
{
IEnumerable<XElement> elements =
from result in xDoc.Descendants("dataroot").Descendants("SalesOrderDetail")
where String.CompareOrdinal(result.Element("LineTotal").Value, "4000.00") > 0
select result;
return elements.Count();
}
LINQ to XML с XPath: 944.9 мс
public static int RunQuery3(XDocument xDoc)
{
return xDoc.XPathSelectElements("//dataroot/SalesOrderDetail[LineTotal>4000.00]").Count();
}
Для наглядности нанесем эти данные на график
Теперь всем видно, что LINQ to XML куда быстрее, чем тоже самое но с использованием XPath. Зачем же Майкрософт написало такую надстройку?
XPath удобнее использовать, когда
- код должен быть читабельным
- при миграции продуктов, использующих XPath исторически
- когда приложение не требует большой производительности от доступа к данным. Мой набор данных имел 120000 строк и при этом XPath работал на 1 секунду медленнее, чем LINQ to XML. Не так уж и плохо, верно?
Но лучше от XPath отказаться, если
- производительность делает вам погоду
- вам необходим sql-похожий синтаксис (ну мало ли, может вы sql-маньяк)
- вам необходима группировка (к примеру, посчитать сумму ордера)
- вам небоходим функционал агрегирования (суммы, среднее и прочее)
Вообщем на те вам, и выбирайте что хотите.