2010-10-06 6 views
6

Ich versuche, einige langsam laufenden Code, der XML mit verschachtelten Schleifen mehrerer Databases schreibt. Ich habe gelesen, dass die Verwendung von linq zum Schreiben der XML schneller wäre. Ich bin in Linq nicht sehr versiert, also hoffte ich, hier Hilfe zu bekommen.Die beste Möglichkeit, DataTables von einem Web Service in XML zu schreiben?

Einige Dinge, die ich erwähnen muss ist, dass die aktuelle Architektur einen Webservice verwendet, der Daten an uns in DataTables zurückgibt. Wir gehen dann durch die Datenblätter (iterativ), und es gibt mehrere, die mehrere verschachtelte Schleifen ergeben.

Beispiel:

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 
     } 

    } 
} 

Wie Sie aus offensichtlichen Gründen sehen, das ist schrecklich langsam. Gibt es eine Möglichkeit, dies mit Linq zu beschleunigen? Was würdest du vorschlagen, um dies effizienter zu gestalten? Es tut mir leid, wenn die Details vage sind ...

Ich schätze jede Hilfe, die jemand anbieten könnte.

+5

Der langsame Teil scheint hier die Aufrufe von WebService zu sein, nicht der XML-Schreibteil. WebService hat eine langsame, hohe Latenz zu ihm =) – Jens

+0

nur ein Gedanke: gegebenen aktuellen Code-Snippet gibt es keine Details, wie XML erstellt wird, und es kann eine große Menge an Daten über das Netzwerk gesendet werden, zu viele Server-Aufrufe und Client -Seite Population von Datentabellen - alle könnten zu Leistungseinbußen führen; Es gibt also keinen ersichtlichen Grund anzunehmen, dass XML-Schreiben ein Engpass ist. –

+0

Können Sie eine andere getStuff-Methode neu schreiben oder hinzufügen, die Ihnen das volle Ergebnis liefert, anstatt Webservice-Aufrufe zu verschachteln? – jmservera

Antwort

14

Das Schreiben der XML ist nicht das, was Sie in diesem Fall verlangsamt. Diese Geschwindigkeit sollte im Vergleich zu der Zeit, die für die Bereitstellung aller Webdienstanrufe benötigt wird, vernachlässigbar sein.

Anstatt sich auf das Schreiben des XML zu konzentrieren, würde ich versuchen herauszufinden, wie die Anzahl der Web-Service-Aufrufe komprimiert werden kann, so dass Sie alle Ihre Daten auf einmal abrufen können.

+3

Web-Service-Anruf in irgendeiner Art von großen Schleife macht mir Angst – Spooks

+0

Ja, ich stimme zu, dass ein ernstes Problem ist der Webservice Anrufe, aber das Problem ist, habe ich keine Kontrolle über den Webservice und ich muss Informationen von jedem vorhergehenden Aufruf in Auftrag bekommen um den Aufruf zu den folgenden Webservice-Methoden zu machen. –

+2

@Johnny: aber dann für 'schnellste Schreib' zu fragen ist nicht so nützlich. –

1

Wenn Sie Linq2Xml verwenden möchten, benötigen Sie auch Linq2Datasets.

Auf diese Weise können Sie Ihre verschachtelten For-Schleifen in eine Linq-Abfrage ändern und in XML auswählen.

Ich erwarte, dass die Verwendung eines XmlWriter jedoch schneller sein kann und sicherlich weniger Speicher verbrauchen wird. Aber es wird etwas mehr Arbeit zu schreiben sein.

+0

Warum sollte er Linq 2 Datasets benötigen? Außerdem basiert der Geschwindigkeitsunterschied zwischen Linq auf XML und XMLWriter. – Adkins

+0

1) Sie können DataRows nicht ohne sie abfragen. Und 2) XmlWriter schreibt direkt, Linq2Xml erstellt zuerst ein Dokument. Dann verwendet einen XmlWriter –

4

Ich fürchte, es gibt keine Heilung für Ihre Notwendigkeit. Weil ich ziemlich sicher bin, was diese Methode langsam macht, ist nicht, wie Sie xml ausschreiben, sondern wie Sie die Daten erfassen. Wenn es eine Verbesserung beim Schreiben von XML geben würde, wäre es nicht in einem bemerkenswerten Verhältnis. Ich empfehle Ihnen, die Art und Weise, wie Sie Daten erfassen, zu überarbeiten. Versuchen Sie, die Anzahl der WebService-Aufrufe zu minimieren.

3

Es klingt, als müssten Sie zuerst Ihre App profilieren - vielleicht wird eine kostenlose Testversion von ANTS oder ähnlich für Sie funktionieren.

1

Mit LINQ to XML und Linq zu Datensätzen können Sie Ihre eigenen XML wie folgt erstellen:

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; 
    } 
0

Sie würden Faktor Ihre Lösung ein wenig neu müssen, um alle loszuwerden, die geschleift WS nennt. Das ist ein ernsthafter Leistungs-Downer.

0

Sie sagen nicht, wie Sie das XML schreiben oder wo Sie das XML schreiben.

Wenn Sie in eine Zeichenfolge schreiben. Stoppen Sie das und schreiben Sie einen Stream.

Wenn Sie in eine gepufferte Zeichenfolge schreiben, dann sehen Sie sich die Größe des Puffers an. Wenn Sie von einer ASP.NET-Seite oder einem Handler schreiben, rufen Sie Response.Flush() in regelmäßigen Abständen auf.

Hier gibt es ein Gleichgewicht, da das Schreiben in einen Puffer fast immer schneller ist als das Schreiben in einen Stream.Das Schreiben in einen Puffer mit automatischer Größenänderung wird jedoch langsamer, je größer die Größe der Größe ist. Darüber hinaus kann alles, was die XML-Verarbeitung anbelangt, erst dann anfangen zu reagieren, wenn sie etwas erhalten, was erst nach dem ersten Flush geschieht.

Hier könnte es also Verbesserungsbedarf geben, obwohl die Aufrufe an den Webservice wahrscheinlich überwiegen, welche Gewinne erzielt werden können. Vielleicht kann dies auch verbessert werden, wenn Sie das Parsen der Webservice-Antwort so umschreiben, dass es Elemente wie sie analysiert werden, was bedeutet, dass Sie die Verarbeitung der Antwort beginnen können, bevor die gesamte Antwort empfangen wird.

Verwandte Themen