Domanda

Ho bisogno di analizzare un file xml che è praticamente un'immagine di una struttura ad albero davvero grande, quindi sto usando la classe XmlReader per popolare l'albero "al volo". A ciascun nodo viene passato solo il blocco xml che si aspetta dal suo genitore tramite la funzione ReadSubtree (). Questo ha il vantaggio di non doversi preoccupare quando un nodo ha consumato tutti i suoi figli. Ma ora mi chiedo se questa sia effettivamente una buona idea, poiché potrebbero esserci migliaia di nodi e durante la lettura dei file di origine .NET ho scoperto che un paio (e probabilmente più) nuovi oggetti vengono creati con ogni chiamata ReadSubtree, e non viene creata alcuna cache per oggetti riutilizzabili (che avevo visto).

Forse ReadSubtree () non è stato pensato per essere utilizzato in modo massiccio, o forse mi sto solo preoccupando per niente e ho solo bisogno di chiamare GC.Collect () dopo aver analizzato il file ...

Spero che qualcuno possa far luce su questo.

Grazie in anticipo.

Aggiornamento:

Grazie per le risposte belle e perspicaci.

Ho dato uno sguardo più approfondito al codice sorgente .NET e l'ho trovato più complesso di quanto immaginassi. Ho finalmente abbandonato l'idea di chiamare questa funzione proprio in questo scenario. Come ha sottolineato Stefan, il lettore xml non viene mai passato agli estranei e posso fidarmi del codice che analizza il flusso xml (che è scritto da me stesso), quindi preferirei forzare ogni nodo a essere responsabile della quantità di dati che essi rubare dallo stream piuttosto che usare la funzione ReadSubtree () non così sottile nel fine di salvare solo poche righe di codice.

È stato utile?

Soluzione

ReadSubTree () ti dà un XmlReader che avvolge l'XmlReader originale. Questo nuovo lettore appare ai consumatori come un documento completo. Questo potrebbe essere importante se il codice che passi alla sottostruttura pensa che stia ottenendo un documento XML standalone. Ad esempio la proprietà Depth del nuovo Reader inizia da 0. È un wrapper piuttosto sottile, quindi non utilizzerai più risorse di quelle che faresti se utilizzassi direttamente l'XmlReader originale, nell'esempio che hai fornito, è piuttosto probabile che non stai davvero ottenendo molto dal lettore di sottostruttura.

Il grande vantaggio nel tuo caso sarebbe che il lettore di sottostruttura non può leggere accidentalmente oltre la sottostruttura. Poiché il lettore di sottostruttura non è molto costoso, tale sicurezza potrebbe essere sufficiente, sebbene sia generalmente più utile quando hai bisogno che la sottostruttura assomigli a un documento o non ti fidi del codice per leggere solo la sua sottostruttura.

Come notato da Will, non vorrai mai chiamare GC.Collect (). Non migliorerà mai le prestazioni.

Altri suggerimenti

Partendo dal presupposto che tutti gli oggetti sono creati sul normale heap gestito, e non sul grande heap di oggetti (cioè meno di 85k), qui non dovrebbe esserci alcun problema, questo è esattamente ciò con cui il GC è stato progettato per gestire.

Suggerirei anche che non è necessario chiamare GC.Collect alla fine del processo, poiché in quasi tutti i casi consentire al GC di pianificare le raccolte da solo consente di lavorare in modo ottimale (vedere questo post sul blog per una spiegazione molto dettagliata di GC che spiega così tanto meglio di me).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top