Я хотел посмотреть, какое из этих предложенных решений работает лучше всего, поэтому я провел несколько сравнительных испытаний. Из интереса я также сравнил методы LINQ с простым старым System.Xml методом, предложенным Грегом. Вариация была интересной и не такой, как я ожидал: самые медленные методы были более чем в 3 раза медленнее, чем самые быстрые .
Результаты, упорядоченные от самого быстрого до самого медленного:
- CreateReader - Instance Hunter (0,113 секунды)
- Простой старый System.Xml - Грег Херлман (0,134 секунды)
- Агрегирование с конкатенацией строк - Майк Пауэлл (0,324 секунды)
- StringBuilder - Vin (0,333 секунды)
- Строка. Присоединиться к массиву - Терри (0,360 секунды)
- String.Concat в массиве - Марчин Косерадзки (0,364)
Метод
Я использовал один XML-документ с 20 одинаковыми узлами (называемый «подсказка»):
<hint>
<strong>Thinking of using a fake address?</strong>
<br />
Please don't. If we can't verify your address we might just
have to reject your application.
</hint>
Числа, показанные в секундах выше, являются результатом извлечения «внутреннего XML» из 20 узлов, 1000 раз подряд и получения среднего (среднего) из 5 запусков. Я не включил время, необходимое для загрузки и анализа XML в XmlDocument
(для метода System.Xml ) или XDocument
(для всех остальных).
Я использовал следующие алгоритмы LINQ: (C # - все принимают XElement
«родителя» и возвращают внутреннюю строку XML)
CreateReader:
var reader = parent.CreateReader();
reader.MoveToContent();
return reader.ReadInnerXml();
Агрегирование с конкатенацией строк:
return parent.Nodes().Aggregate("", (b, node) => b += node.ToString());
StringBuilder:
StringBuilder sb = new StringBuilder();
foreach(var node in parent.Nodes()) {
sb.Append(node.ToString());
}
return sb.ToString();
String.Join для массива:
return String.Join("", parent.Nodes().Select(x => x.ToString()).ToArray());
String.Concat в массиве:
return String.Concat(parent.Nodes().Select(x => x.ToString()).ToArray());
Я не показал здесь алгоритм "Обычная старая System.Xml", так как он просто вызывает .InnerXml на узлах.
Заключение
Если важна производительность (например, много XML, часто анализируемый), я бы использовал метод Даниеля CreateReader
каждый раз . Если вы просто делаете несколько запросов, возможно, вы захотите использовать более краткий метод Майка Aggregate.
Если вы используете XML на больших элементах с большим количеством узлов (возможно, 100), вы, вероятно, начнете видеть преимущество использования StringBuilder
по сравнению с методом Aggregate, но не над CreateReader
. Я не думаю, что методы Join
и Concat
были бы когда-либо более эффективными в этих условиях из-за штрафных санкций за преобразование большого списка в большой массив (даже в случае с небольшими списками)