2010-10-06 7 views
6

Sto cercando di ridefinire un codice di esecuzione lenta che scrive XML utilizzando cicli nidificati di più datatables. Ho letto che usare linq per scrivere l'xml sarebbe più veloce. Non sono esperto di linq, quindi speravo di ottenere un aiuto qui.Il modo migliore per scrivere DataTable da un servizio Web in XML?

Alcune cose che ho bisogno di menzionare è che l'attuale architettura utilizza un webservice che restituisce i dati a noi in DataTable. Quindi passiamo attraverso i datatables (iterativamente), e ce ne sono diversi che risultano diversi loop annidati.

esempio:

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 
     } 

    } 
} 

Come si può vedere, per ovvie ragioni, questo è terribilmente lento. C'è un modo per accelerare usando linq? Cosa vorresti suggerire ragazzi come un approccio più efficiente per refactoring questo? Mi dispiace se i dettagli sono vaghi ...

Apprezzo tutto l'aiuto chiunque potrebbe offrire.

+5

La parte lenta qui sembra essere le chiamate a WebService, non la parte di scrittura XML. WebService ha un ring lento e ad alta latenza =) – Jens

+0

solo un pensiero: dato lo snippet di codice corrente non ci sono dettagli su come viene creato XML, inoltre ci può essere una grande quantità di dati inviati tramite rete, troppe chiamate server e client -una popolazione di tabelle di dati: tutto potrebbe causare un impatto sulle prestazioni; quindi non vi è alcun motivo apparente per supporre che la scrittura XML sia un collo di bottiglia. –

+0

Riesci a riscrivere o aggiungere un altro metodo getStuff che ti dà il risultato completo invece di nidificare le chiamate al servizio web? – jmservera

risposta

14

Scrivere l'XML non è ciò che sta rallentando in questo caso. Tale velocità dovrebbe essere trascurabile rispetto al tempo impiegato per effettuare tutte le chiamate al servizio web.

Invece di concentrarsi sulla scrittura dell'XML, proverei a capire come comprimere il numero di chiamate al servizio Web in modo da poter ottenere tutti i dati contemporaneamente anziché effettuare chiamate annidate in questo modo.

+3

Chiamata al servizio web in qualsiasi tipo di grande ciclo mi spaventa – Spooks

+0

Sì, sono d'accordo sul fatto che un problema serio sono le chiamate al servizio web, ma il problema è che non ho alcun controllo sul servizio web e ho bisogno di ottenere informazioni da ciascuna chiamata precedente in ordine per effettuare la chiamata ai successivi metodi di webservice. –

+2

@Johnny: ma poi chiedere "scrittura veloce" non è così utile. –

1

Se si desidera utilizzare Linq2Xml sono necessari anche Linq2Dataset.

In questo modo è possibile modificare la nidificato per i loop a una query LINQ e selezionare in XML.

mi aspetto che l'utilizzo di un XmlWriter potrebbe essere più veloce, però, e sarà certamente utilizzare meno memoria. Ma sarà un po 'più di lavoro da scrivere.

+0

Perché avrebbe bisogno di set di dati Linq 2? Inoltre, cosa si basa la differenza di velocità tra Linq in XML e XMLWriter. – Adkins

+0

1) Non è possibile eseguire query su DataRows senza di esso. E 2) XmlWriter scrive direttamente, Linq2Xml crea prima un documento. Quindi utilizza un XmlWriter –

4

Ho paura che non ci sia cura per il vostro bisogno. Perché sono abbastanza sicuro che ciò che rende questo metodo lento non è come si scrive xml ma come si acquisiscono i dati. Se ci fosse qualche improvvisazione nello scrivere xml, non sarebbe in una proporzione notevole. Ti suggerisco di rivedere il modo in cui acquisisci i dati. Cerca di minimizzare il numero di chiamate WebService.

3

suona come è necessario al profilo la vostra applicazione prima di tutto - forse una prova gratuita di ANTS o simili lavorerà per voi.

1

utilizzando LINQ to XML e LINQ to set di dati è possibile creare il proprio xml come questo:

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

È necessario re fattore la soluzione un po 'per sbarazzarsi di tutto ciò che in loop WS chiama. Questo è un serio peggioramento delle prestazioni.

0

Non si dice come si scrive l'XML o dove si scrive l'XML.

Se si sta scrivendo su una stringa. Smettila e scrivi un flusso.

Se si sta scrivendo su una stringa bufferizzata, osservare la dimensione del buffer. Se si sta scrivendo da una pagina o gestore ASP.NET, chiamare Response.Flush() a intervalli regolari.

C'è un equilibrio qui, poiché scrivere su un buffer è quasi sempre più veloce di scrivere su uno stream.Tuttavia, la scrittura su un buffer di ridimensionamento automatico diventerà più lenta quanto più deve ridimensionarsi. Inoltre, qualunque sia l'elaborazione dell'XML non può iniziare ad agire finché non inizia a riceverne alcuni, cosa che non succederà fino a dopo il primo flush.

In questo caso è possibile migliorare, sebbene le chiamate al servizio Web superino probabilmente i guadagni possibili. Forse questo può anche essere migliorato, se si riscrive l'analisi della risposta del webservice in modo che sia yields elementi come vengono analizzati, il che significa che è possibile avviare l'elaborazione della risposta prima che venga ricevuta l'intera risposta.

Problemi correlati