Лучший способ написать DataTables из веб-службы в XML? - PullRequest
6 голосов
/ 06 октября 2010

Я пытаюсь провести рефакторинг некоторого медленно работающего кода, который пишет XML, используя вложенные циклы из нескольких таблиц данных. Я прочитал, что с использованием linq для написания XML будет быстрее. Я не очень разбираюсь в linq, поэтому я надеялся получить здесь помощь.

Некоторые вещи, которые я должен упомянуть, это то, что текущая архитектура использует веб-сервис, который возвращает нам данные в dataTables. Затем мы просматриваем таблицы данных (итеративно), и есть несколько, которые приводят к нескольким вложенным циклам.

* * 1004 пример: * * 1005
dt1 = Webservice.getStuff();

for each (datarow r1 in dt1.Rows) {

   dt2 = Webservice.getMoreStuff(r1[col1], r1[col2]);
   // write out some xml

   for each (datarow r2 in dt2.Rows) {

       dt3 = Webservice.getEvenMoreStuff(r2[col1], r2[col2]);
       // write out more xml 

       for each (datarow r3 in dt3.Rows) {
            // write out more xml 
       }

   }
}

Как видите по очевидным причинам, это ужасно медленно. Есть ли способ ускорить это с помощью linq? Что бы вы, ребята, предложили как более эффективный подход к рефакторингу этого? Извините, если детали расплывчаты ...

Я ценю любую помощь, которую может предложить каждый.

Ответы [ 7 ]

14 голосов
/ 06 октября 2010

Написание XML - это не то, что замедляет вас в этом случае .Эта скорость должна быть незначительной по сравнению со временем, затрачиваемым на все вызовы веб-службы.

Вместо того, чтобы сосредоточиться на написании XML, я бы попытался выяснить, как сжимать количество вызовов веб-служб,Вы можете получить все свои данные за один раз, вместо того, чтобы делать подобные вложенные вызовы.

4 голосов
/ 06 октября 2010

Боюсь, нет лекарства от твоей нужды. Потому что я уверен, что этот метод замедляет не то, как вы пишете XML, а то, как вы получаете данные. Если в написании xml будет какое-либо улучшение, это не будет в заметной пропорции. Я предлагаю вам пересмотреть способ сбора данных. Попробуйте свести к минимуму количество вызовов WebService.

3 голосов
/ 06 октября 2010

Похоже, вам нужно в первую очередь профилировать приложение - возможно, вам подойдет бесплатная пробная версия ANTS или аналогичная.

1 голос
/ 06 октября 2010

Используя linq для xml и linq для наборов данных, вы можете создать свой собственный xml следующим образом:

  static void Main(string[] args)
  {

      DataTable t = getStuff("test");

      var xml = new XElement("Main", from row in t.AsEnumerable()
                select new XElement("firstlevel",
                    new XAttribute("a", row["a"]),
                    new XAttribute("b", row["b"]),
                    from row2 in getStuff(row["a"].ToString()).AsEnumerable()
                    select new XElement("secondlevel",
                       new XAttribute("a", row2["a"]),
                       new XAttribute("b", row2["b"]),
                       from row3 in getStuff(row2["a"].ToString()).AsEnumerable()
                       select new XElement("thirdlevel",
                           new XElement("a", row3["a"]),
                           new XElement("b", row3["b"])))));

      Console.WriteLine(xml.ToString());


  }

  private static DataTable getStuff(string s)
  {
      Random r=new Random(s.GetHashCode());
      DataTable t = new DataTable();
      t.Columns.Add("a");
      t.Columns.Add("b");
      for (int i = 0; i < 2; i++)
      {
          t.Rows.Add (r.Next().ToString(), r.Next().ToString());
      }
      return t;
  }
1 голос
/ 06 октября 2010

Если вы хотите использовать Linq2Xml, вам также понадобятся Linq2Datasets.

Таким образом, вы можете изменить вложенные циклы for на запрос Linq и выбрать XML.

Я ожидаю, что использование XmlWriter может быть быстрее, и, конечно, будет использовать меньше памяти Но это будет немного больше работы, чтобы написать.

0 голосов
/ 06 октября 2010

Вы не говорите, как пишете XML или куда пишете XML.

Если вы пишете в строку.Остановите это и напишите поток.

Если вы пишете в буферизованную строку, посмотрите на размер буфера.Если вы пишете со страницы ASP.NET или обработчика, то вызывайте Response.Flush () через регулярные интервалы.

Здесь есть баланс, поскольку запись в буфер почти всегда быстрее записи в поток.Тем не менее, запись в автоматически изменяемый размер буфера будет выполняться медленнее, чем больше будет размер.Более того, независимо от того, обрабатывается ли XML, он не может начать действовать, пока не начнет получать его, что произойдет только после первого сброса.

Следовательно, здесь могут быть возможности для улучшения, хотя вызовыдля веб-службы, скорее всего, перевесят, что может быть сделано.Возможно, это тоже можно улучшить, если переписать ответ веб-службы так, чтобы он yields отображал элементы при их разборе, что означает, что вы можете начать обработку ответа до получения всего ответа.

0 голосов
/ 06 октября 2010

Вам нужно будет немного пересмотреть свое решение, чтобы избавиться от всех зацикленных вызовов WS.Это серьезное снижение производительности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...