2010-03-19 12 views
8

Ich versuche, so viel Leistung wie ich von einem benutzerdefinierten HttpHandler, der Xml-Inhalt dient, zu komprimieren.StringBuilder vs XmlTextWriter

Ich frage mich, welche für die Leistung besser ist. Mit Hilfe der XmlTextWriter Klasse oder Ad-hoc-String Operationen wie:

StringBuilder sb = new StringBuilder("<?xml version="1.0" encoding="UTF-8" ?>");  
sb.AppendFormat("<element>{0}</element>", SOMEVALUE); 

Hat jemand Erfahrung aus erster Hand?

Antwort

12

Wie Josh sagte, dies ist eine Mikro-Optimierung, die Sie nicht einmal in Betracht ziehen sollten, wenn Sie seine Notwendigkeit nicht bewiesen haben. Es ist auch wirklich nicht schwierig zu testen:

static void Main(string[] arguments) 
{ 
    const int iterations = 100000; 

    Stopwatch sw = new Stopwatch(); 
    sw.Start(); 
    string s = CreateUsingStringBuilder("content", iterations); 
    sw.Stop(); 
    Console.WriteLine(String.Format("CreateUsingStringBuilder: {0}", sw.ElapsedMilliseconds)); 

    sw.Reset(); 
    sw.Start(); 
    s = CreateUsingXmlWriter("content", iterations); 
    sw.Stop(); 
    Console.WriteLine(String.Format("CreateUsingXmlWriter: {0}", sw.ElapsedMilliseconds)); 

    Console.ReadKey(); 
} 

private static string CreateUsingStringBuilder(string content, int iterations) 
{ 
    StringBuilder sb = new StringBuilder(); 
    for (int i = 0; i < iterations; i++) 
     sb.AppendFormat("<element>{0}</element>", content); 

    return sb.ToString(); 
} 

private static string CreateUsingXmlWriter(string content, int iterations) 
{ 
    StringBuilder sb = new StringBuilder(); 
    using (StringWriter sw = new StringWriter(sb)) 
    using (XmlWriter xw = XmlWriter.Create(sw)) 
    { 
     xw.WriteStartElement("root"); 
     for (int i = 0; i < iterations; i++) 
      xw.WriteElementString("element", content); 
     xw.WriteEndElement(); 
    } 
    return sb.ToString(); 
} 

Nicht nur die XmlWriter Version ist konsequent schneller von einer Millisekunde oder zwei, es produziert wohlgeformte XML, die die andere Methode nicht.

Aber beide Methoden erstellen XML-Dokumente mit 100.000 Elementen in etwa 60 Millisekunden auf meinem zwei Jahre alten Laptop, eine Zeit, die im Vergleich zu der Zeit, die benötigt wird, um so viele Daten über das Netzwerk zu übertragen, an Bedeutungslosigkeit verliert .

+0

Awesome Job. Ich tat genau das Gleiche an meiner Maschine und kam hierher zurück, um die Ergebnisse zu posten, aber du hast mich geschlagen. Meine Ergebnisse sind im Wesentlichen die gleichen wie das, was Sie gefunden haben. +1 – Josh

+0

Ich stimme zu, dass XmlWriter besser ist, aber wenn wir über Optimierung sprechen, String.Format ist kein Weg zu gehen. sb.Append ("") .Append (Inhalt) .Append (""); macht die StringBuilder-Version 2,5-mal schneller als die andere. –

1

Ehrlich, bis Sie wirklich, wirklich, wirklich, wirklich, wirklich müssen sich um Leistung kümmern ... nicht.

Gehen Sie zuerst mit der wartungsfreundlicheren Lösung und nur dann Kompromisse ein, wenn die Leistung zu einem messbaren Problem wird. XmlTextWriter bietet Ihnen den Vorteil, dass Sie wissen, wie Xml funktionieren soll. StringBuilder nicht und ist daher fehleranfällig. Sie möchten keinen Tag damit verbringen, einen fehlerhaften Knoten irgendwo in Ihrem gnadenlosen Zeichenfolgencode aufzuspüren.

Lassen Sie das Framework für Sie arbeiten.

+0

Ein Teil des XML dient einigen Flash-Dateien, so dass wir bei jeder Anfrage die GESAMTE Inhaltsstruktur an den Client senden müssen. Also kümmern wir uns wirklich um die Leistung. –

+0

Dies ist jedoch eine Mikrooptimierung. Wie hoch ist der Gesamtprozentsatz der Rechenzeit im Vergleich zu ... Netzwerklatenz? Ich bin bereit zu wetten, dass von all den Orten, an denen Sie einige Performance-Gewinne herausbekommen könnten, dies Ihnen den geringsten ROI einbringt. Auch hier müssen Sie einige Messungen vornehmen und die gesamte Pipeline optimieren, nicht nur einen winzigen Aspekt. – Josh

+0

Richtig, wir sind an einem Punkt, wo wir entscheiden, ob wir die XML-Dateien auf den Datenträger schreiben und das Client/Server-Caching übernehmen sollen. Dies wäre die effizienteste, aber stellt uns eine ganze Reihe neuer Probleme vor, also lassen wir das für eine andere Frage. –

2

Wenn SOMEVALUE eine & oder < enthält, wird Sie dieser Ansatz in Schwierigkeiten bringen. Verwenden Sie XML-fähige Klassen, um XML zu generieren. Lesen Sie HOWTO Avoid Being Called a Bozo When Producing XML.

+0

Danke für die Rückmeldung, aber ich bin mir der Probleme bewusst, die mit dem StringBuilder-Ansatz verbunden sind.Wir haben Hilfsklassen, um Zeichen wie & und <> richtig zu entkommen. Meine Frage bezog sich speziell auf die Leistung. –

6

Ich stimme zu, dass XmlWriter besser für die Wartbarkeit von Code ist, aber wenn wir über Leistungsoptimierung sprechen, sollten Sie sowohl XmlWriter als auch StringBuilder.AppendFormat vermeiden, da die Leistung eines Formatierungsprogramms beeinträchtigt wird.

Wechsel

sb.AppendFormat("<element>{0}</element>", content); 

zu

sb.Append("<element>").Append(content).Append("</element>"); 

macht die String Version 2.5 mal schneller als die anderen von Robert Antwort.