Поделиться через


Предварительная атомизация объектов XName (LINQ to XML)

Одним из способов повышения производительности в LINQ to XML является предварительная атомизация объектов XName. Предварительная атомизация состоит в том, что необходимо назначить строке объект XName, прежде чем создавать XML-дерево с использованием конструкторов классов XElement и XAttribute. Затем, вместо того чтобы передавать строку в конструктор, где будет выполнено ее неявное преобразование в объект XName, можно передать инициализированный объект XName.

Таким способом можно повысить производительность при создании большого XML-дерева с рядом повторяющихся имен. Для этого перед построением XML-дерева необходимо объявить и инициализировать объекты XName, а затем в качестве имен элементов и атрибутов указать эти объекты XName вместо строк. Эта техника может дать существенный рост производительности, когда создается большое количество элементов (или атрибутов) с одним и тем же именем.

Чтобы принять решение об использовании предварительной атомизации, протестируйте этот прием в вашем конкретном случае.

Пример

В следующем примере это показано.

XName Root = "Root";
XName Data = "Data";
XName ID = "ID";

XElement root = new XElement(Root,
    new XElement(Data,
        new XAttribute(ID, "1"),
        "4,100,000"),
    new XElement(Data,
        new XAttribute(ID, "2"),
        "3,700,000"),
    new XElement(Data,
        new XAttribute(ID, "3"),
        "1,150,000")
);

Console.WriteLine(root);

В этом примере выводятся следующие данные:

<Root>
  <Data ID="1">4,100,000</Data>
  <Data ID="2">3,700,000</Data>
  <Data ID="3">1,150,000</Data>
</Root>

Следующий пример демонстрирует ту же технику, когда XML-документ находится в пространстве имен.

XNamespace aw = "https://www.adventure-works.com";
XName Root = aw + "Root";
XName Data = aw + "Data";
XName ID = "ID";

XElement root = new XElement(Root,
    new XAttribute(XNamespace.Xmlns + "aw", aw),
    new XElement(Data,
        new XAttribute(ID, "1"),
        "4,100,000"),
    new XElement(Data,
        new XAttribute(ID, "2"),
        "3,700,000"),
    new XElement(Data,
        new XAttribute(ID, "3"),
        "1,150,000")
);

Console.WriteLine(root);

В этом примере выводятся следующие данные:

<aw:Root xmlns:aw="https://www.adventure-works.com">
  <aw:Data ID="1">4,100,000</aw:Data>
  <aw:Data ID="2">3,700,000</aw:Data>
  <aw:Data ID="3">1,150,000</aw:Data>
</aw:Root>

Следующий пример наиболее приближен к реальной ситуации. В этом примере содержимое элементов предоставляется запросом.

XName Root = "Root";
XName Data = "Data";
XName ID = "ID";

DateTime t1 = DateTime.Now;
XElement root = new XElement(Root,
    from i in System.Linq.Enumerable.Range(1, 100000)
    select new XElement(Data,
        new XAttribute(ID, i),
        i * 5)
);
DateTime t2 = DateTime.Now;

Console.WriteLine("Time to construct:{0}", t2 - t1);

Производительность кода в предыдущем примере выше, чем в следующем, где не выполняется предварительная атомизация имен.

DateTime t1 = DateTime.Now;
XElement root = new XElement("Root",
    from i in System.Linq.Enumerable.Range(1, 100000)
    select new XElement("Data",
        new XAttribute("ID", i),
        i * 5)
);
DateTime t2 = DateTime.Now;

Console.WriteLine("Time to construct:{0}", t2 - t1);

См. также

Основные понятия

Производительность (LINQ to XML)

Атомарные объекты XName и XNamespace (LINQ to XML)