XML: GetElementByTagName vs SelectSingleNode Vs Serialize
Premessa: in questi giorni sto giocando con delle piccole Forms Application in .Net, e per le varie configurazioni e dati utilizzo XML (interessa a qualcuno?).
Ieri, mentre scendevo in bici da un paesino alpino a 68 Km/h, mi è nato un dubbio. Per l'accesso a dati XML, per prestazioni, è meglio utilizzare l'ormai storico GetElementByTagName, il quasi nuovo SelectSingleNode con l'XPath, oppure la serializzazione del documento XML in una classe? (Alla faccia della concentrazione ciclistica! Anche questo interessa a qualcuno? Meno di niente, lo so!)
Non mi piace rimanere con i dubbi e ho fatto delle prove in merito. Essendo prove effettuate da me possono non essere del tutto veritiere o esatte, ma accetto qualsiasi smentita a riguardo.
Ma vediamo all'esempio realizzato. Innanzitutto ho scritto questo banale documento XML:
<?xml version="1.0"?> <xml2> <nome1>0</nome1> <nome2>0</nome2> <nome3>0</nome3> <nome4>0</nome4> <nome5>0</nome5> </xml2>
Quindi ho scritto 3 funzioni che eseguono le medesime operazione: prendono il valore numerico di ogni singolo nodo e aumentano tale numero di un'unità. Ecco la prima funzione:
void Funzione1()
{
XmlDataDocument x=new XmlDataDocument();
x.Load(Request.MapPath("XMLFile1.xml" ));
XmlElement root=x.DocumentElement;
XmlNodeList xx;
xx=root.GetElementsByTagName("nome1");
xx[0].InnerText=(Int32.Parse(xx[0].InnerText)+1).ToString();
xx=root.GetElementsByTagName("nome2");
xx[0].InnerText=(Int32.Parse(xx[0].InnerText)+1).ToString();
xx=root.GetElementsByTagName("nome3");
xx[0].InnerText=(Int32.Parse(xx[0].InnerText)+1).ToString();
xx=root.GetElementsByTagName("nome4");
xx[0].InnerText=(Int32.Parse(xx[0].InnerText)+1).ToString();
xx=root.GetElementsByTagName("nome5");
xx[0].InnerText=(Int32.Parse(xx[0].InnerText)+1).ToString();
x.Save(Request.MapPath("XMLFile1.xml" ));
}Molto semplice: letto il documento XML con la funzione GetElementByTagName viene preso il valore interessato e modificato. La seconda funzione utilizza il citato SelectSingleNode:
void Funzione2()
{
XmlDataDocument x=new XmlDataDocument();
x.Load(Request.MapPath("XMLFile1.xml" ));
XmlElement root=x.DocumentElement;
XmlNode xx;
xx=root.SelectSingleNode(@"//nome1");
xx.InnerText=(Int32.Parse(xx.InnerText)+1).ToString();
xx=root.SelectSingleNode(@"//nome2");
xx.InnerText=(Int32.Parse(xx.InnerText)+1).ToString();
xx=root.SelectSingleNode(@"//nome3");
xx.InnerText=(Int32.Parse(xx.InnerText)+1).ToString();
xx=root.SelectSingleNode(@"//nome4");
xx.InnerText=(Int32.Parse(xx.InnerText)+1).ToString();
xx=root.SelectSingleNode(@"//nome5");
xx.InnerText=(Int32.Parse(xx.InnerText)+1).ToString();
x.Save(Request.MapPath("XMLFile1.xml" ));
}
L'ultima tecnica, la serializzazione del contenuto del file XML in una classe si basa su questo codice:
void Funzione3()
{
xml2 x=null;
using( FileStream stream = File.OpenRead( Request.MapPath("XMLFile1.xml" ) ))
{
XmlSerializer serializer = new XmlSerializer( typeof( xml2 ) );
x=(xml2)serializer.Deserialize(stream);
}
x.nome1+=1; x.nome2+=1; x.nome3+=1; x.nome4+=1; x.nome5+=1;
using( FileStream stream = File.OpenWrite( Request.MapPath("XMLFile1.xml" ) ))
{
XmlSerializer serializer = new XmlSerializer( typeof( xml2 ) );
serializer.Serialize( stream, x );
}
}Questa tecnica è anche la più comoda visto che permette l'accesso ai singoli nodi come se fossero propietà di una classe. Confesso che tra le tre tecniche la mia preferita è la seconda: l'accesso ai singoli nodi con il SelectSingleNode o SelectNodes. L'ultima tecnica non l'avevo presa molto in considerazione per una mia ubbia personale: ero sicuro che tra le tre fosse quella con prestazioni peggiori per via della serializzazione e deserializzazione del documento XML in classe.
Mi sbagliavo.
Messe a confronto - nel mio test facevo eseguire questo codice centinaia di volte - per le stesse operazioni ecco i tempi:
- Funzione1: 0,1638 s
- Funzione2: 0,1872 s
- Funzione3: 0,0945 s
??? La tecnica da me utilizza è la più lenta in assoluta e quella che io pensavo fosse la meno prestazionale che è più veloce del quasi 100%. Probabilmente questo è dovuto da una certa lentezza dovuta all'interpretazione della query XPath, ma che la serializzazione permettesse un aumento del genere non me l'aspettavo.
Vado a nascondermi...
Nella stessa categoria
Triplet class non è un oggetto curioso, è utilissimo!!!
Entity Framework e stranezze(*)
Entity Framework. Una tabella due Entity senza discriminazioni
Entity Framework e più tabelle in una entity
L'Entity Framework e le custom class coinvolte nei where...
Entity Framework e l'ereditarietà (Single Table Inheritance)
I più letti del mese



















Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.